| Time Limit: 1000MS | Memory Limit: 65536K | |||
| Total Submissions: 5040 | Accepted: 1932 | Special Judge | ||
Description
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
Source
#include <cstdio>
#include <cstring>
int const MAX = 105;
int const INF = 0xfffffff;
int d[MAX][MAX], map[MAX][MAX], path[MAX][MAX];
int n, m, ans[MAX], mi, cnt;
void init()
{
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= n; j++)
{
d[i][j] = INF;
map[i][j] = INF;
path[i][j] = i;
}
}
}
void Floyd()
{
mi = INF;
for(int k = 1; k <= n; k++)
{
//求环
for(int i = 1; i < k; i++)
{
for(int j = 1; j < i; j++)
{
if(d[i][j] + map[i][k] + map[k][j] < mi)
{
//此时的k值不在d[i][j]的路径中,所以找到一个环
mi = d[i][j] + map[i][k] + map[k][j];
//记录路径把j当起点顺序是: j -> j到i最短路的路径 -> i -> k
int tmp = j;
cnt = 0;
while(tmp != i)
{
ans[cnt++] = tmp;
tmp = path[i][tmp];
}
ans[cnt++] = i;
ans[cnt++] = k;
}
}
}
//求最短路
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= n; j++)
{
if(d[i][k] + d[k][j] < d[i][j])
{
d[i][j] = d[i][k] + d[k][j];
//path[i][j]表示i到j最短路径上j前面的一个点
//所以此时i到j的最短路径上j前一个点为k到j最短路径上j的前一个点
path[i][j] = path[k][j];
}
}
}
}
}
int main()
{
int u, v, w;
scanf("%d %d", &n, &m);
init();
for(int i = 0; i < m; i++)
{
scanf("%d %d %d", &u, &v, &w);
if(d[u][v] > w) //找最小环遇到平行边时取其最小边权
{
d[u][v] = d[v][u] = w;
map[u][v] = map[v][u] = w;
}
}
Floyd();
if(mi == INF)
printf("No solution.\n");
else
{
printf("%d", ans[0]);
for(int i = 1; i < cnt; i++)
printf(" %d", ans[i]);
printf("\n");
}
}POJ 1734 Sightseeing trip (Floyd 最小环+记录路径)
原文地址:http://blog.csdn.net/tc_to_top/article/details/43707139