「POJ1734」Sightseeing trip
Description
In the town there are N crossing points numbered from 1 to N and M two-way roads numbered from 1 to M. Two crossing points can be connected by multiple roads, but no road connects a crossing point with itself. Each sightseeing route is a sequence of road numbers y_1, …, y_k, k>2. The road y_i (1<=i<=k-1) connects crossing points x_i and x_{i+1}, the road y_k connects crossing points x_k and x_1. All the numbers x_1,…,x_k should be different.The length of the sightseeing route is the sum of the lengths of all roads on the sightseeing route, i.e. L(y_1)+L(y_2)+…+L(y_k) where L(y_i) is the length of the road y_i (1<=i<=k). Your program has to find such a sightseeing route, the length of which is minimal, or to specify that it is not possible,because there is no sightseeing route in the town.
Input
Output
Sample Input
1 2 3 4 5 6 7 8 |
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 |
1 3 5 2 |
题解
floyd找最小环。。刚学的。。在松弛前找环。。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> #include<set> #define inf 500000000 #define ll long long using namespace std; inline int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } int n,m,mn=inf,top; int ans[105]; int dis[105][105],mp[105][105],cen[105][105]; void get(int x,int y) { int mid=cen[x][y]; if(!mid) { ans[++top]=y; return; } get(x,mid);get(mid,y); } void floyd() { for(int k=1;k<=n;k++) { for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { if(i==j||i==k||j==k)continue; if(dis[i][j]+mp[i][k]+mp[k][j]<mn) { mn=dis[i][j]+mp[i][k]+mp[k][j]; top=0; ans[++top]=i; get(i,j); ans[++top]=k; } } for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { if(i==j||i==k||j==k)continue; if(dis[i][k]+dis[k][j]<dis[i][j]) { dis[i][j]=dis[i][k]+dis[k][j]; cen[i][j]=k; } } } if(mn==inf) puts("No solution."); else for(int i=1;i<=top;i++) printf("%d ",ans[i]); printf("\n"); } int main() { memset(mp,127/3,sizeof(mp)); memset(dis,127/3,sizeof(dis)); n=read();m=read(); for(int i=1;i<=m;i++) { int u=read(),v=read(),w=read(); dis[u][v]=dis[v][u]=mp[u][v]=mp[v][u]=min(mp[u][v],w); } floyd(); return 0; } |