POJ 1734 Sightseeing trip(Floyd)

题目传送门

题目中文翻译:

Description

桑给巴尔岛上的阿德尔顿镇有一家旅行社,它已决定为其客户提供除了许多其他名胜之外的景点。为了尽可能地从景点赚取收入,该机构已经接受了一个精明的决定:有必要找到在同一地点开始和结束的最短路线。你的任务是写一个找到这样的路线的程序。

镇内有N个交叉点,编号从1N。同时有M条双向路,编号从1M两个交叉点可以由多条道路连接,但没有道路将交叉点与自己连接。每条观光环线都是一系列道路编号y_1...y_kk> 2。道路y_i1 <= i <= k-1)连接交叉点x_ix_ {i + 1},道路y_k连接交叉点x_kx_1。所有的数字x_1...x_k应该是不同的。观光路线的长度是观光路线上所有道路长度的总和,即Ly_1+ Ly_2+ ... + L y_k)其中Ly_i)是道路y_i的长度(1 <= i <= k)。你的程序必须找到这样一条观光路线,其长度最短,或者说明这是不可能的,因为镇上没有观光环线。

Input

第一行输入包含两个正整数:交叉点N <= 100和道数M <= 10000。 接下来的M行中的每一行描述一条道路。 它包含3个正整数:第一个交点的编号,第二个交点的编号和道路的长度(小于500的正整数)。

Output

输出中只有一行,一个字符串如果没有任何观光路线,输出'No solution.' 或者列出最短观光路线上所有交叉点的编号,以便让我们知道如何设计路线(即从我们对观光路线的定义中的数字x_1x_k),由空格分离。如果有多条最小长度的观光路线,您可以输出其中任何一条。

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

解题思路:

本题其实就是求一个图中的最小环的路径.

AC代码:

 1 #include<cstdio>
 2 #include<iostream>
 3 
 4 using namespace std;
 5 
 6 int g[105][105],dis[105][105],path[105][105];
 7 //path[i][j]表示i到j的最短路径中j的前一个点
 8 //dis[i][j]表示i到j最短的那条路径 
 9 int n,m,ans[105],mi,cnt; 
10 
11 inline void chushihua() {
12     for(int i = 1;i <= n; i++)
13         for(int j = 1;j <= n; j++)
14             dis[i][j] = g[i][j] = 0x3f3f,path[i][j] = i;
15 }
16 
17 inline void _read() {
18     int u,v,w;
19     for(int i = 1;i <= m; i++) {
20         scanf("%d%d%d",&u,&v,&w);
21         dis[u][v] = dis[v][u] = g[u][v] = g[v][u] = min(w,dis[u][v]);
22     }
23 }
24 
25 inline void Floyd() {
26     mi = 0x3f3f;
27     for(int k = 1;k <= n; k++){
28         for(int i = 1;i < k; i++) 
29             for(int j = 1;j < i; j++) {
30                 if(dis[i][j] + g[i][k] + g[k][j] < mi) {
31                     mi = dis[i][j] + g[i][k] + g[k][j];
32                     int tmp = j;
33                     cnt = 0;
34                     while(tmp != i) {
35                         ans[cnt++] = tmp;
36                         tmp = path[i][tmp];
37                     }
38                     ans[cnt++] = i;
39                     ans[cnt++] = k;
40                 }
41             }
42     for(int i = 1;i <= n; i++)
43         for(int j = 1;j <= n; j++) {
44             if(dis[i][k] + dis[k][j] < dis[i][j]) {
45                 dis[i][j] = dis[i][k] + dis[k][j];
46                 path[i][j] = path[k][j];
47             }
48         }
49     }
50 }
51 
52 inline void _print() {
53     if(mi == 0x3f3f)
54         printf("No solution.");
55     else {
56         for(int i = 1;i < cnt; i++)
57             printf("%d ",ans[i]);
58         printf("%d",ans[0]);
59     }
60         
61 }
62 
63 int main()//简洁易懂的主函数 
64 {
65     scanf("%d%d",&n,&m);
66     chushihua();
67     _read();
68     Floyd();
69     _print();
70     return 0;
71 }

猜你喜欢

转载自www.cnblogs.com/lipeiyi520/p/11290269.html