算法:
在一个图中求出一个路径长度最小的环。首先,我们可以想到迪杰斯特拉算法,计算出 dis[src,i] + map[i][src] ,然后维护一个最大值就好了。但是这样做的话,在计算 dis[src,i] 时有可能会把 map[i][src] 包含进去,那么怎么办呢,我们可以枚举每一条边,先删掉,然后求 dis[src,i] ,再计算 dis[src,i] + map[i][src] ,这样就不会错了。但是,我们有更好的算法, floyd 算法求最小环,我们枚举一个环的起点 i 和终点
j ,那么 map[i][k]+map[k][j]+dp[i][j] 就是一个最小候选环,其中 dp[i][j] 是没有被比 k 大的结点松弛过,也就是说,dp[i][j] 没有经过 k 结点,那么这个过程完全可以在floyd 算法的三重循环下一起完成。最后在算法的过程中加入路径记录,最后就可以输出路径了。
代码:
int N,M;
int map[SIZE][SIZE];
int dp[SIZE][SIZE];
int pre[SIZE][SIZE];
int ans;
int path[SIZE];
int top;
void floyd()
{
int i,j,k;
for(k=1;k<=N;k++){
int tmp;
for(i=1;i<k;i++)
for(j=i+1;j<k;j++){
tmp=dp[i][j]+map[i][k]+map[k][j];
if(tmp<ans){
ans=tmp;
top=0;
int p=j;
while(p!=i)
path[top++]=p,p=pre[i][p];
path[top++]=i;
path[top++]=k;
}
}
for(i=1;i<=N;i++)
for(j=1;j<=N;j++)
if(dp[i][j]>dp[i][k]+dp[k][j])
dp[i][j]=dp[i][k]+dp[k][j],
pre[i][j]=pre[k][j];
}
}