利用Floyd的性质:即循环到k时,d[i][j] (I<k,j<k)在比k小的点内已到达最短距离 在枚举k的同时 k也是我们分切环的点,
d[i][j]+a[i][k]+a[k][j]
因为d[I][j]必然不经过k,所以a[I][k]+a[k][j]必然是另外一条到达j的路径,同时我们也保证了d[i][j]为I->j的最短距离
我们也可以这样理解:枚举到最优路径的最大点k的时候,必然会有d[I][j]+a[i][k]+a[k][j]
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
#define INF 0x3f3f3f3f
int n,m,ans=INF;
int a[110][110],d[110][110],f[110][110];
vector<int>vec;
void get(int x,int y){
if(f[x][y]==0) return ;
get(x,f[x][y]);
vec.push_back(f[x][y]);
get(f[x][y],y);
}
int main()
{
cin>>n>>m;
memset(a,0x3f,sizeof a);
for(int i=1;i<=n;i++) a[i][i]=0;
for(int i=1;i<=m;i++){
int x,y,z;
cin>>x>>y>>z;
a[y][x]=a[x][y]=min(a[x][y],z);
}
memcpy(d,a,sizeof a);
for(int k=1;k<=n;k++){
for(int i=1;i<k;i++)
for(int j=i+1;j<k;j++)
if((long long)d[i][j]+a[j][k]+a[k][i]<ans){
ans=d[i][j]+a[j][k]+a[k][i];
vec.clear();
vec.push_back(i);
get(i,j);
vec.push_back(j);
vec.push_back(k);
}
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(d[i][j]>d[i][k]+d[k][j]){
d[i][j]=d[i][k]+d[k][j];
f[i][j]=k;
}
}
if(ans==INF){
puts("No solution.");
return 0;
}
for(int i=0;i<vec.size();i++)
cout<<vec[i]<<' ';
cout<<endl;
return 0;
}