其他分享
首页 > 其他分享> > POJ1734 Sightseeing trip (Floyd求最小环)

POJ1734 Sightseeing trip (Floyd求最小环)

作者:互联网

学习了一下用Floyd求最小环,思路还是比较清晰的。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<vector>
 6 using namespace std;
 7 int a[310][310],d[310][310],pos[310][310];
 8 int n,m,ans=0x3f3f3f3f;
 9 vector<int> path;//用vector的领接表储存最小环方案 
10 void get_path(int x,int y){
11     if(pos[x][y]==0) return ;
12     get_path(x,pos[x][y]);
13     path.push_back(pos[x][y]);
14     get_path(pos[x][y],y);
15 } 
16  
17 int main(){
18     cin>>n>>m;
19     memset(a,0x3f,sizeof(a));
20     for(int i=1;i<=n;i++) a[i][i]=0;
21     for(int i=1;i<=m;i++){
22         int x,y,z;
23         cin>>x>>y>>z;
24         a[y][x]=a[x][y]=min(a[x][y],z);//选择两点之间最短的路径 
25     }
26     memcpy(d,a,sizeof(a));//将a全部复制到d中
27     for(int k=1;k<=n;k++){
28         for(int i=1;i<k;i++)
29             for(int j=i+1;j<k;j++)
30             if((long long)d[i][j]+a[j][k]+a[k][i]<ans){//更新答案 
31                 ans=d[i][j]+a[j][k]+a[k][i];
32                 path.clear();
33                 path.push_back(i);
34                 get_path(i,j);
35                 path.push_back(j);
36                 path.push_back(k);
37             }
38         for(int i=1;i<=n;i++)//依据每一个k作为中转点更新ij最短路径 
39         for(int j=1;j<=n;j++)
40         if(d[i][j]>d[i][k]+d[k][j]){
41             d[i][j]=d[i][k]+d[k][j];
42             pos[i][j]=k;
43         }
44     } 
45     if(ans==0x3f3f3f3f){
46         cout<<"No solution.";
47         return 0;
48     }
49     for(int i=0;i<path.size();i++)
50         cout<<path[i]<<" ";
51 }

总结一下:主要是用k作为中转点,对于每一个k:i和j都是小于k的,先更新最小环的答案,然后用此时的k更新每个i,j的最短距离,为下一次循环(也就是k+1)作准备。

方程: min{d[i][j]+a[j][k]+a[k][i]} (1<=i<j<k)。

其中pos[i][j]=k,代表ij最短路间经过了k,用于get_path()。

标签:POJ1734,get,int,310,pos,Floyd,path,include,trip
来源: https://www.cnblogs.com/yhxnoerror/p/16099052.html