题解 | #Forsaken喜欢独一无二的树#

Forsaken喜欢独一无二的树

https://ac.nowcoder.com/acm/problem/53074

解题思路:

用Kruskal的方法对边排序,遇到边权相同的一段单独处理:

①不考虑两点已经在并查集内部的(边权更小)

②将其他边拿出来,若不在相同并查集,则进行合并;如果已经在,也是相同边权的边导致的,计入答案即可

#include <bits/stdc++.h>
using namespace std ;
#define int long long
#define inf 0x3f3f3f3f3f3f3f3f
const int maxN = 2e5+10 ;

struct EDGE {
    int u, v, val ;
    bool operator < (const EDGE &b) const {
        return val < b.val ;
    }
}edges[maxN<<1] ;

struct DSU {
    vector<int> fa, sz ;
    DSU(int n) : fa(n+1), sz(n+1) {
        for(int i=1 ; i<=n ; i++)
            fa[i] = i , sz[i] = 1 ;
    }
    int find(int x) {
        return fa[x]==x ? x : fa[x]=find(fa[x]) ;
    }
    void merge(int x, int y) {
        x = find(x), y = find(y) ;
        if(x==y)    return ;
        //fx -> fy
        if(sz[x]>sz[y])    swap(x,y) ;
        sz[y] += sz[x], fa[x]=y ;
    }
} ;

signed main() {
    int n , m;    cin >> n >> m ; 
    for(int i=1 ; i<=m ; i++) 
        cin >> edges[i].u >> edges[i].v >> edges[i].val ;
    
    DSU dsu(n) ;
    sort(edges+1, edges+m+1) ;
    int cnt = 0 , ans=0 ;
    for(int l=1 , r=1 ; l<=m&&r<=m ; r=l=r+1) {
        while(r<=m-1 && edges[r].val==edges[r+1].val)
            r++ ;
        if(l==r) {
            if(dsu.find(edges[l].u)==dsu.find(edges[l].v))
                continue ;
            dsu.merge(edges[l].u, edges[l].v) ;
            cnt++ ;
        }else {
            vector<int> v ;
            for(int i=l ; i<=r ; i++) {
                if(dsu.find(edges[i].u)==dsu.find(edges[i].v))
                    continue ;
                v.push_back(i) ;                
            }
            for(auto &i:v) {
                if(dsu.find(edges[i].u)==dsu.find(edges[i].v)) {
                    ans += edges[i].val ;
                }else 
                    dsu.merge(edges[i].u, edges[i].v) , cnt++ ;
            }
        }
    }
    cout << ans << endl ;
    return 0 ;
}
全部评论

相关推荐

04-08 23:14
已编辑
南阳理工学院 算法工程师
本人情况:26届双非本科,两段实习经历,目前拿到的都是实习的offer,一个校招的都没有,他们都说先实习,然后等拿到毕业证了直接转正,我又害怕干三个月给我叉出去面试题也发一下吧###&nbsp;杭州问尔信息技术后端登录你是怎么做的?JWT令牌你了解过吗?他虽然是一段字符串,他表达了什么东西?怎么解析出来信息和过期时间?JWT令牌怎么续期?如果我拉黑一个账号,要怎么做?两种方案(有无redis)mongodb和mysql的区别?mongodb和mysql分别实用于什么项目?选型你会怎么选?数据库的事务,那些地方需要使用,那些地方不需要使用?他会影响什么性能?mysql和pgsql有什么差异你知道吗?消息队列&nbsp;redis也有,为什么要用mq?前后端会部署吗?docker会用吗?内部通信前端&nbsp;async和&nbsp;await你知道吗?异步编程的原理是什么?vue3&nbsp;为什么你改变一个字符串&nbsp;前端会跟着改动AI工具会用什么?你会怎么用?###&nbsp;仲财通常用的锁有哪些synchronize和ReentrantLock的区别分布式锁了解吗?分布式事务mysql表字段sql优化什么时候用索引索引什么时候会失效mysql事务ioc一些项目应用问题###&nbsp;观妙科技项目问题...zset的架构是什么样子的线程池突然队列被打满了怎么办?如果上游和下游都无法控制,该怎么维护select&nbsp;*&nbsp;from&nbsp;user&nbsp;where&nbsp;age&gt;20&nbsp;order&nbsp;by&nbsp;update_time&nbsp;索引设计检索过程是什么样的冒泡排序和快排,有什么区别怎么判断链表有没有环###&nbsp;观妙科技-二面项目部分...线程池的核心参数有哪些你是怎么用线程池的JMMG1模型跳表介绍一下平衡二叉树TCP为什么要三次握手?说一下hashmap红黑树的特征你有什么学习的方法
牛马人的牛马人生:对学院本而言很强了
点赞 评论 收藏
分享
lafael:?你认真的?这几个项目已经烂大街到不能再烂了。你变个名字我都认可你好歹有点改进,怎么连名字都不换
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务