标签:namespace code printf min else algo logs blog std
其实floyd求最小环就相当于找出一个一条只包括1到k-1中节点的路径,然后把这个路径与k这个节点相连。这样是正确的原因是,最小环中一定有一个最大节点k,当最外层节点是k时,我们一定会枚举到k两端的两个节点,这样就统计出了答案。至于为什么不能直接用最短路径,而是要用前k-1个节点跑出来的最短路径,是因为不知道最短路径有没有经过k。
反正这个算法是对的就对了。
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn=105, INF=1e9;
int n, m, minm, dis[maxn][maxn], ori[maxn][maxn];
int main(){
while (~scanf("%d%d", &n, &m)){
for (int i=1; i<=n; ++i)
for (int j=1; j<=n; ++j){
dis[i][j]=dis[j][i]=INF;
ori[i][j]=ori[j][i]=INF;
}
int x, y, v; minm=INF;
for (int i=1; i<=m; ++i){
scanf("%d%d%d", &x, &y, &v);
ori[x][y]=ori[y][x]=min(ori[x][y], v);
dis[x][y]=dis[y][x]=min(ori[x][y], v);
}
for (int k=1; k<=n; ++k){
for (int i=1; i<=n; ++i)
for (int j=1; j<=n; ++j)
//三点都要不相同。ij不一定,但是相同的点ori一定是INF。
//所以只需要判断i!=j。
if (i!=j&&dis[i][j]!=INF&&ori[j][k]!=INF
&&ori[k][i]!=INF)
minm=min(minm, dis[i][j]+ori[j][k]+ori[k][i]);
for (int i=1; i<=n; ++i)
for (int j=1; j<=n; ++j)
dis[i][j]=min(dis[i][j], dis[i][k]+dis[k][j]);
}
if (minm==INF) printf("It's impossible.\n");
else printf("%d\n", minm);
}
}
标签:namespace code printf min else algo logs blog std
原文地址:http://www.cnblogs.com/MyNameIsPc/p/7905673.html