poj1734 Sightseeing trip(Floyd求无向图最小环)

 1 #include <iostream>
 2 #include <cstring>
 3 #include <cstdio>
 4 #include <algorithm>
 5 #include <vector>
 6 using namespace std;
 7 
 8 typedef long long ll;
 9 const int maxn = 100 + 5;
10 const int inf = 0x3f3f3f3f;
11 int n, m, ans;
12 int mp[maxn][maxn], dis[maxn][maxn], pos[maxn][maxn];
13 vector<int> path;    //记录路径
14 inline void getpath( int x, int y ){
15     if( pos[x][y]==0 ) return;
16     getpath( x, pos[x][y] );
17     path.push_back(pos[x][y]);
18     getpath( pos[x][y], y );
19 }
20 
21 inline void floyd(){
22     ans = inf;
23     for( int k=1; k<=n; k++ ){
24         for( int i=1; i<k; i++ )
25             for( int j=i+1; j<k; j++ )
26                 if( (ll)dis[i][j] + mp[j][k] + mp[k][i] < ans ){
27                     ans = dis[i][j]+mp[j][k]+mp[k][i];  
28                     path.clear();      //发现更优起点,清除之前路径
29                     path.push_back(i);   //该行到32行 按顺序插入才能构成环
30                     getpath( i, j );
31                     path.push_back(j);
32                     path.push_back(k);
33                 }
34         for( int i=1; i<=n; i++ )
35             for( int j=1; j<=n; j++ )
36                 if( dis[i][j] > dis[i][k]+dis[k][j] ){  //此处要按dis[i][k]+dis[k][j]更新最短距离 而不是mp[i][k]+mp[k][j]
37                     dis[i][j] = dis[i][k]+dis[k][j];
38                     pos[i][j] = k;
39                 }
40     }
41 }
42 
43 int main(){
44     scanf("%d%d", &n, &m);
45     memset( mp, inf, sizeof(mp) );
46     memset( pos, 0, sizeof(pos) );
47     for( int i=0; i<=n; i++ ) mp[i][i] = 0;
48     for( int i=0; i<m; i++ ){
49         int u, v, w;
50         scanf("%d%d%d", &u, &v, &w);
51         if( w<mp[u][v] ) mp[u][v] = mp[v][u] = w;
52      }
53     memcpy( dis, mp, sizeof(mp) );
54     floyd();
55     if( ans==inf ){
56         puts("No solution.");
57         return 0;
58     }
59     for( int i=0; i<path.size(); i++ )
60         printf("%d ", path[i]);
61     puts("");
62 
63     return 0;
64 }
65 
66 /*
67 Sample Input
68 5 7
69 1 4 1
70 1 3 300
71 3 1 10
72 1 2 16
73 2 3 100
74 2 5 15
75 5 3 20
76 
77 Sample Output
78 1 3 5 2
79 */

 

转载于:https://www.cnblogs.com/WAautomaton/p/10845771.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值