Floyd算法就是通过n次枚举中间点k来使i到j的距离松弛为最短,而本题就是在枚举k的时候找环,具体思路见代码!
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define inf 999999
#define N 105
int n,len,ans,map[N][N],dis[N][N],post[N][N],path[N];
void floyd()
{
for(int k=1;k<=n;k++)
{
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(i==k||j==k||i==j)continue;
if(ans>dis[i][j]+map[j][k]+map[k][i]) //这里就是找环的过程,因为当前的k点还没出现在i到j的最短路径中,所以k可以出现在连接i到j形成环的另一条边中
{
ans=dis[i][j]+map[j][k]+map[k][i];
len=0;
int t=i;
path[len++]=t; //记录路径
while(post[t][j]!=j)
{
t=post[t][j];
path[len++]=t;
}
path[len++]=j;
path[len++]=k;
}
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(dis[i][j]>dis[i][k]+dis[k][j]) //Floyd求最短路
{
dis[i][j]=dis[i][k]+dis[k][j];
post[i][j]=post[i][k]; //更新路径
}
}
}
}
}
int main()
{
//freopen("a.txt","r",stdin);
int m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
map[i][j]=dis[i][j]=inf;
post[i][j]=j; //post[i][j]记录的是i到j的最短路径中i的下一点
}
}
while(m--)
{
int l,x,y;
scanf("%d%d%d",&x,&y,&l);
if(map[x][y]>l)
{
map[x][y]=map[y][x]=l;
dis[x][y]=dis[y][x]=l;
}
}
ans=inf;
floyd();
if(ans==inf)printf("No solution.");
for(int i=0;i<len;i++)
{
if(i)printf(" ");
printf("%d",path[i]);
}
printf("\n");
return 0;
}