当前位置: 代码迷 >> 综合 >> 带权并查集 HDU - 3038 How Many Answers Are Wrong
  详细解决方案

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

热度:41   发布时间:2023-12-22 14:17:10.0

题意:

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;
}

 

  相关解决方案