浏览器标题切换
浏览器标题切换end

HDU3047-Zjnu Stadium-带权并查集

题意

给出n和m,n代表n个人,m代表接下去有m行数据需要进行判断。

接下去m行,每行给出数据x,y,z表示x的位置加上距离z就是y所在的位置。

输出有多少个是和前面的例子矛盾的,输出矛盾个数。

思路

这题是并查集的变形,也就是带权并查集,表示在俩俩合并的时候需要对于距离进行存储判断

注意

这题的样例自己纯推不太好推。

参考博客,可以看下这个博客的图,解释样例解释的很清楚:https://blog.csdn.net/hj1107402232/article/details/9921311

AC代码

#include<stdio.h>
#include<map>
#include<iostream>
#include<string.h>
#include<algorithm>
#include<stack>
#include<cmath>
#include<vector>
using namespace std;
 typedef long long ll;
 const int N=50020;

 int f[N],d[N],n;

 void init()
 {
     for(int i=1;i<=n;i++)
     {
         f[i]=i;
         d[i]=0;
     }
 }
 int getf(int x)
 {
     if(f[x]==x)
         return x;
     else
     {
         int t=f[x];//找它的父节点
         f[x]=getf(f[x]);
         d[x]=d[x]+d[t];//d[x](为x到根节点的距离)更新为它到它父节点的距离+父节点到根节点的距离
         return f[x];
     }
 }

 void merge(int x,int y)
 {
     int t1=getf(x);
     int t2=getf(y);
     if(t1!=t2)
         f[t2]=t1;
     return;
 }

 int main()
 {
     int m,x,y,z;
     while(~scanf("%d %d",&n,&m))
     {
         init();
         int ans=0;
         for(int i=0;i<m;i++)
         {
             scanf("%d %d %d",&x,&y,&z);
             int fx=getf(x),fy=getf(y);
             if(fx==fy)
             {
                 int w=d[y]-d[x];
                 if(w!=z)
                     ans++;
             }
             else
             {
                 merge(x,y); //f[fy]=x;
                 d[fy]=d[x]+z-d[y];
             }
         }
         cout<<ans<<endl;
     }
     return 0;
 }
posted @   抓水母的派大星  阅读(174)  评论(0编辑  收藏  举报
编辑推荐:
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」
点击右上角即可分享
微信分享提示