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