如果能确定只有简单环的话可以直接tarjan
最小环的floyed解法:
若为有向图:
floyed后直接找一个最小的dis[i][i]即可
本题为无向图:
大体思路是根据dp的性质
假设k连接i,j 形成首尾相接的环,此时由于dp的阶段性k还没有被放到最短路里,所以这样一定是环,为什么呢,因为无向图的话,想象一条链,从头走到尾再走回头,floyed过程中就会更新dis[i][i]
而为什么i枚举到k-1?因为i若等于k则形成一个点 不再是一条边
注意重边和溢出
因为是三个数相加 INF设为int的三分之一以下
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
#define debug(x) cerr << #x << "=" << x << endl;
const int MAXN = 1010;
int g[1010][1010],n,m;
const int INF = 1e8;//INF大了会溢出 设为0x7fffffff/3也不错
int d[1010][1010];
int minn;
int main() {
while(cin >> n >> m) {
minn = INF;
for(int i=1; i<=n; i++) {
for(int j=1; j<=n; j++) {
d[i][j] = d[j][i] = g[j][i] = g[i][j] = INF;
}
}
for(int i=1; i<=m; i++) {
int u,v,w;
cin >> u >> v >> w;
g[u][v]=g[v][u]=d[u][v]=d[v][u]=w;
}
memcpy(d,g,sizeof(g));
for(int k=1; k<=n; k++) {
for(int i=1; i<k; i++)
for(int j=i+1; j<k; j++)
if(d[i][j]+g[i][k]+g[k][j]<minn)
minn=d[i][j]+g[i][k]+g[k][j];
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
if(d[i][k] < INF && d[k][j] < INF)
d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
}
if(minn == INF)
cout << "No solution." << endl;
else
cout << minn << endl;
}
return 0;
}

本文介绍了一种求解无向图中最小环的具体算法,使用Floyd算法进行迭代,并结合动态规划的思想来找到最短环。通过实例代码展示了算法实现细节。
381

被折叠的 条评论
为什么被折叠?



