FZU2090 旅行社的烦恼 巧妙floyd 最短路

分析:floyd看似很好理解,实际上是状态转移,具体的解释参照这里

       http://www.cnblogs.com/chenying99/p/3932877.html

       深入理解了floyd后,这个题就可做了

       首先,枚举最短路径的最大点,k,然后由于floyd的更新性质,更新到k时,

      数组中存的是“只能使用第1号到第k-1号点作为中间媒介时,点i到点j之间的最短路径长度”

      这样枚举在k两边的这两个节点,i和j这样就可以,这两个直接的最短路已经确定,保证i<j,这样就找到了以i为最大节点的一个环

    最后不断比较统计就行了,这样可以保证不重不漏

  

#include <stdio.h>
#include <iostream>
#include <vector>
#include <math.h>
#include <algorithm>
#include <string.h>
#include <string>
using namespace std;
typedef long long LL;
const int N=1e2+5;
const int INF=5e8;
int mp[N][N],dis[N][N];
int main()
{
    int T;
    scanf("%d",&T);
    while(T--){
      int n,m;
      scanf("%d%d",&n,&m);
      for(int i=1;i<=n;++i)
        for(int j=1;j<=n;++j)
          mp[i][j]=INF;
      for(int i=0;i<m;++i){
        int u,v,w;
        scanf("%d%d%d",&u,&v,&w);
        if(w<mp[u][v])
          mp[u][v]=mp[v][u]=w;
      }
      for(int i=1;i<=n;++i)
        for(int j=1;j<=n;++j)
          dis[i][j]=mp[i][j];
      int mx=INF,cnt=0;
      for(int k=1;k<=n;++k){
        for(int i=1;i<k;++i)
          for(int j=i+1;j<k;++j)
            if(mx>mp[i][k]+mp[j][k]+dis[i][j])
              mx=mp[i][k]+mp[j][k]+dis[i][j],cnt=1;
            else if(mx==mp[i][k]+mp[j][k]+dis[i][j])++cnt;
        for(int i=1;i<=n;++i)
          for(int j=1;j<=n;++j)
            dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);    
      }
      if(cnt==0)printf("-1\n");
      else printf("%d %d\n",mx,cnt);
    }
    return 0;
}
View Code

 

posted @ 2016-04-13 20:29  shuguangzw  阅读(188)  评论(0编辑  收藏  举报