The best trade path(FLoyd法入门)

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 incomeIn 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;
 }


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值