[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 }

 

posted @ 2017-11-26 20:17  skylee03  阅读(102)  评论(0编辑  收藏  举报