题目链接:https://vjudge.net/problem/13143/origin
分析:模板题,理解floyd 的在 i , j 路径中没有包含k(因为此时k未用来更新),即可写出最小环
在INF这里wa了两发,习惯值 1e9 不是最大值(查找时判断一下可以避免,但。。。懒了)
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
#define maxn 105
#define INF 0x7ffffff
int n , m;
int mp[maxn][maxn];
int edge[maxn][maxn];
int path[maxn][maxn];
int ans[maxn] ;
int cnt;
int mm ;
void deal()
{
mm = INF;
for(int k = 1 ; k <= n ; ++k)
{
for(int i = 1 ; i < k ; ++i)
{
for(int j = i + 1 ; j < k ; ++j)
{
int x = edge[i][j] + mp[k][i] + mp[k][j];
if( x < mm )
{
mm = x;
int tmp = j;
cnt = 0;
while(tmp != i)
{
ans[cnt++] = tmp;
tmp = path[i][tmp];
}
ans[cnt++] = i;
ans[cnt++] = k;
}
}
}
for(int i = 1 ; i <= n ; ++i)
{
for(int j = 1 ;j <= n ; ++j)
{
if( edge[i][j] > edge[i][k] + edge[k][j] )
{
edge[i][j] = edge[i][k] + edge[k][j];
path[i][j] = path[k][j];
}
}
}
}
}
void init()
{
for(int i = 0 ; i <= n ; ++i){
for(int j = 0 ; j <= n ; ++j){
edge[i][j] = mp[i][j] = INF;
path[i][j] = i;
}
}
}
int main()
{
while( cin >> n >> m )
{
init();
for(int i = 0 ; i < m ; ++i)
{
int a,b,c;
scanf("%d %d %d",&a,&b,&c);
edge[a][b] = edge[b][a] = min(edge[a][b],c);
mp[a][b] = mp[b][a] = edge[a][b];
}
deal();
if( mm == INF )
{
printf("No solution.\n");
continue;
}
for(int i = 0 ; i < cnt ; ++i)
{
printf("%d%s",ans[i],(i==cnt-1)?"\n":" ");
}
}
return 0;
}