Floyd求最小环

原理:不讲。

模板如下。

 1 #include<cstdio>    
 2 #include<cstring>    
 3 #define find_min(a,b) a<b?a:b    
 4     
 5 const int N=109;    
 6 const int INF=0x7ffffff;    

 7 int f[N][N],dis[N][N],pre[N][N],path[N],n,m,num;  
 8     
 9 int main()    
10 {    
11         scanf("%d%d",&n,&m);
12       
13         for(int i=1;i<=n;i++)   
14             for(int j=1;j<=n;j++) 
15                 f[i][j]=dis[i][j]=INF,pre[i][j]=i;  
16                 
17         while(m--)
18         {    
19             int a,b,c;
20             scanf("%d%d%d",&a,&b,&c);    
21             f[a][b]=f[b][a]=dis[a][b]=dis[b][a]=find_min(f[a][b],c);    
22         }    
23     
24         int min=INF;    
25         for(int k=1;k<=n;k++)//最短路径外一点将最短路首尾链接,那么就得到一个最小环,枚举中间点  
26         {  
27             for(int i=1;i<k;i++)   
28                 for(int j=i+1;j<k;j++)
29                 {    
30                     //求最小环不能用两点间最短路松弛,因为(i,k)之间的最短路,(k,j)之间的最短路可能有重合的部分    
31                     //所以f[][]其实是不更新的,这里和单纯的floyd最短路不一样    
32                     //dis[i][j]保存的是 i 到 j 的最短路权值和,(i->j)    
33                     int tmp=dis[i][j]+f[i][k]+f[k][j];//这里k分别和i还有 j在f[][]中直接相连    
34                     if(tmp<min)
35                     {    
36                         min=tmp;num=0;    
37                         int p=j;    
38                         while(p!=i)//回溯  
39                         {  
40                             path[num++]=p;    
41                             p=pre[i][p];//pre[i][j]表示i->j最短路径上j前面的一个点    
42                         }    
43                         path[num++]=i; path[num++]=k;    
44                     }    
45                 }  
46             
47             for(int i=1;i<=n;i++)   
48                 for(int j=1;j<=n;j++)   
49                     if(dis[i][j]>dis[i][k]+dis[k][j])
50                     {    
51                         dis[i][j]=dis[i][k]+dis[k][j];//dis[][]保存两点间最短距离    
52                         pre[i][j]=pre[k][j];    
53                     }    
54                 
55         }    
56         if(min==INF)puts("No solution.");    
57         else
58         {    
59             printf("%d",path[0]);    
60             for(int i=1;i<num;i++)    
61                 printf(" %d",path[i]);    
62             puts("");    
63         }  
64     return 0;    
65 }    
View Code


例题:POJ 1734 Sightseeing trip

          HDU    1599     find the mincost route

         

原文地址:https://www.cnblogs.com/adelalove/p/8486680.html