您现在的位置是:主页 > news > 公司想建网站/青岛网站建设制作

公司想建网站/青岛网站建设制作

admin2025/5/19 13:53:03news

简介公司想建网站,青岛网站建设制作,百度不收录网站文章,国家企业信用信息公示官网Description 从前有一位旅者,他想要游遍天下所有的景点。这一天他来到了一个神奇的王国:在这片土地上,有n个城市,从1到n进行编号。王国中有m条道路,第i条道路连接着两个城市ai,bi,由于年代久远&#xff0c…

公司想建网站,青岛网站建设制作,百度不收录网站文章,国家企业信用信息公示官网Description 从前有一位旅者,他想要游遍天下所有的景点。这一天他来到了一个神奇的王国:在这片土地上,有n个城市,从1到n进行编号。王国中有m条道路,第i条道路连接着两个城市ai,bi,由于年代久远&#xff0c…

Description

从前有一位旅者,他想要游遍天下所有的景点。这一天他来到了一个神奇的王国:在这片土地上,有n个城市,从1到n进行编号。王国中有m条道路,第i条道路连接着两个城市ai,bi,由于年代久远,所有的道路都已经不能使用。如果要修复第i条道路,需要wi的时间。为了更好的旅行,旅者想要将某些道路修复,使得1号城市能够到达n号城市,2号城市能够到达n-1号城市..k号城市能够到达n-k+1号城市。为了满足他的要求,请问最少需要多少时间去修复道路。无解请输出-1。

Input

第一行:n,m,k

接下来m行:ai,bi,wi

含义如上所述。

Output

输出共一行:最少需要多少时间修复道路。如果始终无法满足旅者的要求,请输出-1。

Sample Input

5 5 21 3 43 5 22 3 13 4 42 4 3

Sample Output

9

Data Constraint

20%的数据满足:k <= 2, n<= 10, m <= 20

40%的数据满足:k <= 3, n<=100, m<=1000

70%的数据满足:k<=4, n<=1000, m<=1000

100%的数据满足:k<=4, n<=10000, m<=10000, n >= 2*k, wi<= 1000, 1 <= ai, bi <= n 

Hint

样例解释:

Solution

此题考查选手对stenir tree的灵活应用。

【Stenir tree问题】

在一张带权无向图中,有若干个黑色点,求一棵最小生成树,使得所有的黑色点都在该树上。

【解决方法】

我们用F[u][S]代表一棵以u节点为根的树,这棵树上的黑色节点情况用状态S表示,F[u][S]代表这棵树最小的权值和是多少。根据状态表示,我们可得转移方程:

F[u][S] = min(F[v][S’]+w[u][v]+F[u][S-S’]),其中S’|S = S。

注意到这个方程在转移时可能会出现循环,因为我们不知道应该是用F[u][S]来更新F[v][S]还是反之而行。也就是说当S相等时,我们应该用最短路的思想来进行转移(利用spfa或者dijkstra)。

假定spfa的复杂度为O(m),黑色点有p个,则整个算法的复杂度为O(3^p * m)。

【原问题】

回到我们的原问题,我们需要得到若干个连通块,使得i号点和n-i+1号点位于同一个连通块,由于所有的边权都是非负的,所有连通块一定是一棵树,也就是说我们需要得到若干棵树,使得i号点和n-i+1号点一定位于同一棵树内。

【解决办法】

在解决stenir tree的问题过程中,我们得到了F[u][S]数组,令good[S]=min(F[u][s])。则我们知道了将S状态联通所需要的最小代价。若在S状态中,     存在一个黑色点i不能对应黑色点n-i+1,则我们将这个状态删除。接下来就是要将这些状态组合起来,使得他们的权值和最小。我们可以用DP解决。

 

于是整个算法的复杂度为O(3^p * m)

鄙人觉得此题解已讲解详细,故co之为人所见

Code

#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 10010
#define I int
#define F(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
I n,m,k,x,y,z,f[N][300],bz[N],p[N];
I t[N*2],nx[N*2],l[N],s[N*2],q[N*8],ans[N];
I read(){I x=0;char ch=getchar();while(ch<'0'||ch>'9'){ch=getchar();}while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x;
}
void add(I x,I y,I z){t[++t[0]]=y;nx[t[0]]=l[x];s[t[0]]=z;l[x]=t[0];
}
int pd(I x){F(i,1,k){if(((x>>(i-1))&1)^((x>>(k+i-1))&1)) return 0;}return 1;
}
int main(){freopen("travel.in","r",stdin);freopen("travel.out","w",stdout);n=read();m=read();k=read();F(i,1,m){x=read();y=read();z=read();add(x,y,z);add(y,x,z);}memset(f,127,sizeof(f));memset(p,127,sizeof(p));F(i,1,k) f[i][1<<(i-1)]=f[n-i+1][1<<(k+i-1)]=0;F(i,k+1,n-k) f[i][0]=0;F(S,1,(1<<(k*2))-1){F(i,1,n){F(T,1,S-1){if((T|S)==S&&f[i][S-T]!=f[0][0]){for(int j=l[i];j;j=nx[j]){if(f[t[j]][T]==f[0][0]) continue;f[i][S]=min(f[i][S],f[t[j]][T]+s[j]+f[i][S-T]);	}}}}F(i,1,n){bz[i]=1;q[i]=i;}I hd=1,tl=n;while(hd<=tl){I x=q[hd++],y=f[x][S];bz[x]=0;if(y==f[0][0]) continue;for(int i=l[x];i;i=nx[i]){if(f[t[i]][S]>y+s[i]){f[t[i]][S]=y+s[i];if(!bz[t[i]]){bz[t[i]]=1;q[++tl]=t[i];}}}}F(i,1,n) p[S]=p[S]>f[i][S]?f[i][S]:p[S];}memset(ans,127,sizeof(ans));I inf=ans[0];ans[0]=0;F(S,1,(1<<(k*2))-1){F(T,0,S-1){if(ans[T]!=inf&&p[S-T]!=inf&&((T|S)==S)&&pd(S)&&pd(T)) ans[S]=min(ans[S],ans[T]+p[S-T]);}}if(ans[(1<<(k*2))-1]!=inf) printf("%d\n",ans[(1<<(k*2))-1]);else printf("-1\n");return 0;
}


作者:zsjzliziyang 
QQ:1634151125 
转载及修改请注明 
本文地址:https://blog.csdn.net/zsjzliziyang/article/details/97967551