题意; 输入 n ,m 。 表示 图中有n个点,m表示有m条边,每天边的形式为 x y d
问是否存在点数超过三个的环,若有多个,求出环最小长度。
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int inf = 99999999;
const int M = 105;
int dist[M][M];
int group[M][M];
int n, m, ans;
void init(){
for(int i = 1; i <= n; i++){
for(int j = 1; j <= n; j++){
dist[i][j] = inf;
group[i][j] = inf;
}
}
}
void floyd(){
ans = inf;
for(int k = 1; k <= n; k++){
for(int i = 1; i <= n; i++){
for(int j = 1; j <= n; j++){
if(i !=j && i != k && k != j)
ans = min(ans, dist[i][j] + group[i][k] + group[k][j]);
//dist[i][j] 表示i 到j的最短距离,
//group用于保留原题数据,很奇妙的算法
//dist[i][j] group[i][k] + group[k][j] 表示点数超过三个的环的长度(且是最小的)
}
}
for(int i = 1; i <= n; i++){
for(int j = 1; j <= n; j++){
dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]);
//松弛各点间的距离
}
}
}
if(ans != inf){
printf("%d\n", ans);
}else {
printf("It's impossible.\n");
}
}
int main()
{
int x, y, d;
while(scanf("%d%d", &n, &m) != EOF){
init();
for(int i = 0; i < m; i++){
scanf("%d%d%d", &x, &y, &d);
if(dist[x][y] > d) {
dist[x][y] = dist[y][x] = d;
group[x][y] = group[y][x] = d;
}
}
floyd();
}
return 0;
}