http://cstest.scu.edu.cn/soj/contest/problem.action?cid=332&alias=F
The best trade path
Description
Businessman is uesed to establishing trade-path between different cities in order to get a stable income(In this problem, a trade-path is a set of roads starting at a city and ending at the same city which should go through at least one other city.)And the long-time cargo transportation is often accompanied by great risk.
Given a map of this region and the time from some city to another city, please help businessman find the trade-path which takes the least time.
Input
There are several test cases. The first line is the number of cases.
For each test case the first line contains two integer n,m, (1<=n<=100,0<=m<=10000) which denote the number of cities and road (directed road). The following m lines contains three integer ai,bi,di which means that It takes di time from the city ai to the city bi. (1<=ai,bi<=n,di<=1000000).
Output
For each case, print the time of the shortest trade-route at the beginning of a new line. If there is no legal trade-route in the map, print -1.
Sample Input
3
5 10
1 2 10
1 3 5
2 3 2
2 4 1
3 2 3
3 4 9
3 5 2
4 5 4
5 1 7
5 4 6
4 6
1 2 10
2 1 60
1 3 20
3 4 10
2 4 5
4 1 50
4 5
1 2 10
1 3 20
3 4 10
2 4 5
1 4 50
Sample Output
5
65
-1
Hint
题意:
给出n个城市和m条路线。求是否存在回路,如果有输出最小回路,如果没有则输出—1,最短路径问题
思路:这里可以用FLoyd法,求两点间的最短距离,这里的特殊情况就是求起点和终点一样的最短路径;
这里其实就是裸的floyd算法:
首先要初始化,将没有通道的路径初始化为无穷大;
其次:不断更新重边,因为如果产生重边的话,那么最终就是以最后一组数来定下他们的权值,因此,要将产生的重边更新为较小值,否则出错
最后:利用floyd算法求两点的最短巨离,再从从中找到起点和终点一样的路径找到最小值(这里的最小值也要初始化为无穷大)(若最终求得最小值仍为无穷大则说明无回路出现,否则输出答案)
#include<stdio.h>
#include<string.h>
#include <iostream>
using namespace std;
const int N=100+10;
const int inf=0x3f3f3f3f;
int n,m;
int map[N][N],temp[N][N];
void floyd()
{
for(int k=1;k<=n;k++)
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{if(map[i][k]<inf&&map[k][j]<inf)
{if(map[i][j]>=map[i][k]+map[k][j])
map[i][j]=map[i][k]+map[k][j];
}
}
}
int main()
{
int T,i;
int s,t,d;
int min;
scanf("%d",&T);
while(T--)
{ min=inf;
memset(map,inf,sizeof(map));
memset(temp,inf,sizeof(temp));
scanf("%d%d",&n,&m);
for(i=0;i<m;i++)
{
scanf("%d%d%d",&s,&t,&d);
map[s][t]=d;
if(temp[s][t]<map[s][t])//更新重边得到最小值,这一步必不可少否则出错!!!
map[s][t]=temp[s][t];
temp[s][t]=map[s][t];
}
floyd();
//for(i=1;i<=n;i++)
//printf("%d ",map[i][i]);
for(i=1;i<=n;i++)
if(min>map[i][i])
min=map[i][i];
if(min==inf)
printf("-1\n");
else
printf("%d\n",min);
}
return 0;
}