题目链接
floyd算法可以算出任意2个点之间的距离,对于(i,j)之间的距离,可以加一个没有用过的点k,且(i,k) ,(k,j)是存在的,那么就可以在 (i,j) 之间形成一个环。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<vector>
#include<queue>
#include<iostream>
using namespace std;
#define LL __int64
#define cl(a,b) memset(a,b,sizeof(a))
#define pb push_back
const int maxn = 102;
const int inf = 1<<25;
const __int64 mod = 1000000007;
int dp[maxn][maxn];
int cost[maxn][maxn];
void init(int n){
for(int i=0;i<=n;i++){
for(int j=0;j<=n;j++){
cost[i][j]=inf;
cost[i][i]=0;
}
}
}
pair<int,int> floyd(int n){
for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)dp[i][j]=cost[i][j];
int ans=0;
int mi = inf;
for(int k=1;k<=n;k++){
for(int i=1;i<k;i++){
for(int j=i+1;j<k;j++){
if(mi>dp[i][j]+cost[i][k]+cost[k][j]){
ans=1;
mi=dp[i][j]+cost[i][k]+cost[k][j];
}
else if(mi==dp[i][j]+cost[i][k]+cost[k][j]){
ans++;
}
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
dp[i][j]=min(dp[i][j],dp[i][k]+dp[k][j]);
}
}
}
return make_pair(mi,ans);
}
int main(){
int T;scanf("%d",&T);
while(T--){
int n,m;scanf("%d%d",&n,&m);
init(n);
for(int i=0;i<m;i++){
int x,y,z;scanf("%d%d%d",&x,&y,&z);
cost[x][y]=cost[y][x]=min(cost[x][y],z);
}
pair<int,int> ans=floyd(n);
if((ans.first)>=inf){
puts("-1");continue;
}
printf("%d %d\n",ans.first,ans.second);
}
return 0;
}