题目传送门
题目中文翻译:
Description
桑给巴尔岛上的阿德尔顿镇有一家旅行社,它已决定为其客户提供除了许多其他名胜之外的景点。为了尽可能地从景点赚取收入,该机构已经接受了一个精明的决定:有必要找到在同一地点开始和结束的最短路线。你的任务是写一个找到这样的路线的程序。
镇内有N个交叉点,编号从1到N。同时有M条双向路,编号从1到M。两个交叉点可以由多条道路连接,但没有道路将交叉点与自己连接。每条观光环线都是一系列道路编号y_1,...,y_k,k> 2。道路y_i(1 <= i <= k-1)连接交叉点x_i和x_ {i + 1},道路y_k连接交叉点x_k和x_1。所有的数字x_1,...,x_k应该是不同的。观光路线的长度是观光路线上所有道路长度的总和,即L(y_1)+ L(y_2)+ ... + L (y_k)其中L(y_i)是道路y_i的长度(1 <= i <= k)。你的程序必须找到这样一条观光路线,其长度最短,或者说明这是不可能的,因为镇上没有观光环线。
Input
第一行输入包含两个正整数:交叉点N <= 100和道数M <= 10000。 接下来的M行中的每一行描述一条道路。 它包含3个正整数:第一个交点的编号,第二个交点的编号和道路的长度(小于500的正整数)。
Output
输出中只有一行,一个字符串。如果没有任何观光路线,输出'No solution.' 或者列出最短观光路线上所有交叉点的编号,以便让我们知道如何设计路线(即从我们对观光路线的定义中的数字x_1到x_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 }