[HDU1599]find the mincost route
题目大意:
求无向图最小环(超过3个点)。
思路:
Floyd。
每次转移前,更新一次最小环。
也就是说现在用(i,k)和(k,j)更新(i,j)这条边,我们就看一下(i,k),(k,j),(i,j)这三条路径所构成的环是否是最小环。
但是这样会有一个问题,就是这些路径之间有可能会有重叠部分,导致最终结果并不是一个环。
因此我们可以考虑用数组w保留每条边的最初状态,然后求环的时候用w[i][k]+w[k][j]+dis[i][j]。
注意可能会有重边。
1 #include<cstdio> 2 #include<cctype> 3 #include<algorithm> 4 inline int getint() { 5 register char ch; 6 while(!isdigit(ch=getchar())); 7 register int x=ch^'0'; 8 while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0'); 9 return x; 10 } 11 const int inf=0x7fffffff; 12 const int N=101; 13 int w[N][N],dis[N][N]; 14 int main() { 15 int n,m; 16 while(~scanf("%d%d",&n,&m)) { 17 for(register int i=1;i<=n;i++) { 18 for(register int j=1;j<=n;j++) { 19 w[i][j]=dis[i][j]=inf; 20 } 21 } 22 while(m--) { 23 const int u=getint(),v=getint(); 24 dis[u][v]=dis[v][u]=w[u][v]=w[v][u]=std::min(w[u][v],getint()); 25 } 26 int ans=inf; 27 for(register int k=1;k<=n;k++) { 28 for(register int i=1;i<=n;i++) { 29 if(dis[i][k]==inf) continue; 30 for(register int j=i+1;j<=n;j++) { 31 if(dis[k][j]==inf) continue; 32 if(w[i][k]!=inf&&w[k][j]!=inf&&dis[i][j]!=inf) { 33 ans=std::min(ans,w[i][k]+w[k][j]+dis[i][j]); 34 } 35 dis[i][j]=dis[j][i]=std::min(dis[i][j],dis[i][k]+dis[k][j]); 36 } 37 } 38 } 39 if(ans!=inf) { 40 printf("%d\n",ans); 41 } else { 42 puts("It's impossible."); 43 } 44 } 45 return 0; 46 }