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为最大节点的一个环
最后不断比较统计就行了,这样可以保证不重不漏
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#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; }