poj 1734 (最小环)

floyd的核心思想就是动态规划从k=0->n来松弛i->j的路径,

因为floyd的外层到k时,i->j的最短路上肯定没有k。所以我们可以先找环,再更新。如果存在的话,那么肯定是i->j  然后j->k->i。这样保证了i->j这条路不经过k。

View Code
 1 // File Name: 1734.cpp
 2 // Author: Missa
 3 // Created Time: 2013/2/7 星期四 16:39:58
 4 
 5 #include<cstdio>
 6 #include<cstring>
 7 using namespace std;
 8 
 9 const int inf = 100000000;
10 const int maxn = 110;
11 int n,m,num;
12 int dis[maxn][maxn];
13 int path[maxn][maxn];
14 int g[maxn][maxn];
15 int res[maxn];
16 
17 void dfs(int i,int j)
18 {
19     int k=path[i][j];
20     if(k==0)
21     {
22         res[num++]=j;
23         return ;
24     }
25     dfs(i,k);
26     dfs(k,j);
27 }
28 
29 int main()
30 {
31     while(~scanf("%d%d",&n,&m))
32     {
33         for(int i=1;i<=n;i++)
34         {
35             for(int j=i+1;j<=n;j++)
36                 g[i][j]=g[j][i]=dis[i][j]=dis[j][i]=inf;
37             g[i][i]=dis[i][i]=0;
38         }
39         for(int i=0;i<m;i++)
40         {
41             int x,y,z;
42             scanf("%d%d%d",&x,&y,&z);
43             if(z<g[x][y])
44             {
45                 dis[x][y]=dis[y][x]=z;
46                 g[x][y]=g[y][x]=z;
47             }
48         }
49         int ans=inf;
50         memset(path,0,sizeof(path));
51         for(int k=1;k<=n;k++)
52         {
53             for(int i=1;i<k;i++)
54                 for(int j=i+1;j<k;j++)//求环
55                     if(dis[i][j] +g[i][k]+g[k][j] <ans)
56                     {
57                         ans=dis[i][j]+g[i][k]+g[k][j];
58                         num=0;
59                         res[num++]=i;
60                         dfs(i,j);
61                         res[num++]=k;
62                     }
63             for(int i=1;i<=n;i++)
64                 for(int j=1;j<=n;j++)
65                     if(dis[i][k]+dis[k][j]<dis[i][j])//松弛
66                     {
67                         dis[i][j]=dis[i][k]+dis[k][j];
68                         path[i][j]=k;
69                     }
70         }
71         if(ans==inf)
72             puts("No solution.");
73         else
74         {
75             printf("%d",res[0]);
76             for(int i=1;i<num;i++)
77                 printf(" %d",res[i]);
78             printf("\n");
79         }
80     }
81     return 0;
82 }

 

posted @ 2013-02-07 18:04  Missa  阅读(473)  评论(0编辑  收藏  举报