题意:
n个点m条边,如果图中有环,输出最小环路径,否则输出"No solution."
思路:
开一个pre[][]数组
pre[i][j]表示i到j最短路上j的入点(前驱)
每当任意两点i,j之间的最短路更新,同时更新pre[i][j]
查找路径操作具体看代码
code:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<vector>
using namespace std;
const int maxm=105;
const int inf=1e8;
int d[maxm][maxm];//最短路图(可改)
int g[maxm][maxm];//原图(不改)
int pre[maxm][maxm];//pre[i][j]表示i到j最短路中j的入点(前驱)
vector<int>res;
int n,m;
void getpath(int i,int j,int k){
res.clear();
while(j!=i){
res.push_back(j);
j=pre[i][j];
}
res.push_back(i);
res.push_back(k);
}
void floyd(){
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
d[i][j]=g[i][j];
}
}
int ans=inf;
for(int k=1;k<=n;k++){
for(int i=1;i<k;i++){
for(int j=i+1;j<k;j++){
int t=g[i][k]+g[k][j]+d[i][j];
if(t<ans){
ans=t;
getpath(i,j,k);
}
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
int t=d[i][k]+d[k][j];
if(t<d[i][j]){
d[i][j]=t;
pre[i][j]=pre[k][j];
}
}
}
}
if(ans==inf){
puts("No solution.");
}else{
int len=res.size();
for(int i=0;i<len;i++){
if(i)putchar(' ');
printf("%d",res[i]);
}
puts("");
}
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){//init
for(int j=1;j<=n;j++){
g[i][j]=(i==j)?0:inf;
pre[i][j]=i;
}
}
for(int i=1;i<=m;i++){
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
g[a][b]=g[b][a]=min(g[a][b],c);
}
floyd();
return 0;
}