1. 程式人生 > >poj1734(求最小環)

poj1734(求最小環)

sin sub ems 距離 pat clu lin .com limit

4923: Poj1734 Sightseeing trip

Time Limit: 1 Sec Memory Limit: 128 MB
Submit: 15 Solved: 6
[Submit][Status][Web Board]

Description

給定一張無向圖,求圖中一個至少包含3個點的環,環上的節點不重復,並且環上的邊的長度之和最小。該問題稱
為無向圖的最小環問題。在本題中,你需要輸出最小環的方案,若最小環不唯一,輸出任意一個均可。若無解,輸
出"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; }

 

poj1734(求最小環)