HDU 4514 湫湫系列故事——设计风景线 (并查集)

判断有没有环路,我个人认为还是并查集效率要高,而且复杂度要比dfs低,性价比很好

这道题的要求,第一判断是否有环,如果没有环,就输出最长的路径

我们可以想到一个无向图如果没有环的话,一定就是两种形态,一种是一棵树,另一种就是森林

那么要求最长路径的话,也就是要求树的半径

大致的思想明白了,就说一下细节吧

并查集的思想就是在图中找一个节点作为根,凡是和这点在一个连通分量里面的点,都插入到这个根上,是的前驱是这个根或者前前驱是这个根,由于并查集的维护,使得这儿数据结构很高效,具体的内容可以找书看。有一个重要的性质就是,如果发现了一条边的两个点的根是一个,说明加上这条边,图中就存在环了,画个图看看,就显而易见了。

详细见代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
const int N=100022;
int f[N], num[N];
int find( int x )
{
    return ( f[x] == x ) ? x : f[x] = find(f[x]);
}
int main()
{
    int n, m, t1, t2;
    int u, v, w;
    int ans;
    bool fl;
    while( scanf("%d%d",&n,&m) != EOF ) {
        for(int i = 1; i <= n; i++ ) f[i] = i;
        memset( num, 0, sizeof(num) );
        fl = true;
        ans = 0;
        while( m-- ) {
            scanf("%d%d%d", &u, &v, &w);
            t1 = find( u ); //找父节点
            t2 = find( v );
            if( !fl ) continue;
            if( t1 == t2 ) fl=false;
            else {
                f[t1] = t2;  //将两连通分量连起来,也就是将其中一个父节点变为另一个父节点的父节点
                num[t2] += num[t1] + w;
                if ( ans < num[t2] ) ans = num[t2];
            }
        }
        if( fl ) {
            printf("%d\n", ans);
            continue;
        }
        printf("YES\n");
    }
}


评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值