Vijos1046 观光旅游 - 最小环模板

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

如果能确定只有简单环的话可以直接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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值