poj1734(求最小环)
4923: Poj1734 Sightseeing trip
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 15 Solved: 6
[Submit][Status][Web Board]
Description
给定一张无向图,求图中一个至少包含3个点的环,环上的节点不重复,并且环上的边的长度之和最小。该问题称
为无向图的最小环问题。在本题中,你需要输出最小环的方案,若最小环不唯一,输出任意一个均可。若无解,输
出"No solution."。图的节点数不超过100。
为无向图的最小环问题。在本题中,你需要输出最小环的方案,若最小环不唯一,输出任意一个均可。若无解,输
出"No solution."。图的节点数不超过100。
Input
Output
Sample Input
5 7
1 4 1
1 3 300
3 1 10
1 2 16
2 3 100
2 5 15
5 3 20
Sample Output
1 3 5 2
d[i][j]在外层循环刚开始时表示1...k-1的最短路距离那么d[i][j]+a[i][k]+a[k][j]构成一个环,更新最小环即可
#include<cstdio> #include<cstring> #include<vector> #include<algorithm> #include<stack> using namespace std; const int maxn=300+10; const int nil=0x3f3f3f3f; int a[maxn][maxn],pos[maxn][maxn],d[maxn][maxn]; vector<int>path; stack<int>s; void getpath(int x,int y){ if(pos[x][y]==-1) return ; getpath(x,pos[x][y]); path.push_back(pos[x][y]); getpath(pos[x][y],y); } int main(){ int n,m,x,y,w; scanf("%d%d",&n,&m); for (int i=1;i<=n;i++){ for (int j=1;j<=n;j++){ a[i][j]=d[i][j]=nil; pos[i][j]=-1; } } for (int i=1;i<=m;i++){ scanf("%d%d%d",&x,&y,&w); d[x][y]=d[y][x]=a[x][y]=a[y][x]=min(a[x][y],w); } int ans=nil; for (int k=1;k<=n;k++){ for (int i=1;i<k;i++) for (int j=i+1;j<k;j++) if(ans>(long long)d[i][j]+a[i][k]+a[k][j]){ ans=d[i][j]+a[i][k]+a[k][j]; path.clear(); path.push_back(i); getpath(i,j); path.push_back(j); path.push_back(k); } for (int i=1;i<=n;i++){ for (int j=1;j<=n;j++){ if(d[i][j]>d[i][k]+d[k][j]){ d[i][j]=d[i][k]+d[k][j]; pos[i][j]=k; } } } } if(ans==nil) printf("No solution."); else { printf("%d",path[0]); for (int i=1;i<path.size();i++) printf(" %d",path[i]); } return 0; }