带权并查集 HDU - 3038 How Many Answers Are Wrong

题意:

n个值,m次查询,每次查询给出(u,v,w)表示位置u到v的值的和,求与前面已出现过的查询中冲突的个数,同时认为这个查询是错误的,忽略它。

题解:

带权并查集。

关于带权并查集可以参考这篇博客

注意连边的时候使用(u-1,v,w)或者(u,v+1,w),不然如果出现(1,10,100),(7,10,28),(1,3,32),(4,6,41) 就查不出来。

代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define db double
#define m_p make_pair
#define p_b push_back
#define For(i,a,b) for(int i=a;i<=b;i++)
#define ls (rt<<1)
#define rs ((rt<<1)|1)
#define mst(a,b) memset(a,b,sizeof(a))
const int MAXN=2e5+5;
const db eps=1e-8;
const int INF=0x3f3f3f3f;
const int mod=1e9+7;
const int seed=131;
int n,m;
int fa[MAXN],sum[MAXN];
void init(int n){
	For(i,0,n) fa[i]=i,sum[i]=0;
} 
int find(int x){
	if(fa[x]!=x){
		int tt=fa[x];
		fa[x]=find(fa[x]);
		sum[x]+=sum[tt];
	}
	return  fa[x];
}
int main(){
//	freopen("in.txt","r",stdin);
	while(~scanf("%d %d",&n,&m)){
		init(n);
		int u,v,w,ans=0;
		For(i,1,m){
			scanf("%d %d %d",&u,&v,&w);
			int fu=find(u-1),fv=find(v);
			if(fu!=fv){
				fa[fu]=fv;
				sum[fu]=-sum[u-1]+sum[v]+w;
			}
			else if(w!=sum[u-1]-sum[v]) ans++;
		}
		cout<<ans<<"\n";
	}
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值