HDU 3038 带权并查集,区间
2017-06-08 10:35
309 查看
题意:TT是一个男孩,FF是一个女孩,然后FF告诉TT n个区间以及他们的区间和,然后TT判断有多少个是和之前矛盾的。
这个讲的蛮清楚
我们如果要判断是不是和前面矛盾的话,我们就需要把前面的记录下来。
sum[i]:i到它最左边的值
dis[i]:i的最左边
还是要画图好理解点~
如果两个点的最左端点相同的话,我们就可以直接判断其中是不是矛盾的
如果不同的话,还要更新最左端点。
这个讲的蛮清楚
我们如果要判断是不是和前面矛盾的话,我们就需要把前面的记录下来。
sum[i]:i到它最左边的值
dis[i]:i的最左边
还是要画图好理解点~
如果两个点的最左端点相同的话,我们就可以直接判断其中是不是矛盾的
如果不同的话,还要更新最左端点。
#include <iostream> #include <algorithm> #include <cstdio> #include <cstring> #include <cmath> #include <queue> #include <map> #include <set> using namespace std; int ans=0; const int maxn = 2e5+10; int dis[maxn],sum[maxn]; int n,m; void init() { for(int i=0;i<=n;i++) dis[i]=i; memset(sum,0,sizeof(sum)); } int findf(int k) { if(k==dis[k]) return k; else { int t=dis[k]; dis[k]=findf(dis[k]); sum[k]+=sum[t]; } return dis[k]; } void bing(int x,int y,int data) { int a=findf(x); int b=findf(y); if(a==b) { if((sum[x]+data)!=sum[y]) ans++; return ; } else if(a<b) { sum[b]=sum[x]+data-sum[y]; dis[b]=a; } else { sum[a]=sum[y]-(sum[x]+data); dis[a]=b; } return ; } int main() { while( scanf("%d %d",&n,&m)!=EOF){ init(); ans=0; for(int i=0;i<m;i++) { int x,y,data; scanf("%d %d %d",&x,&y,&data); x--; bing(x,y,data); } printf("%d\n",ans); } return 0; }
相关文章推荐
- HDU 3038 带权并查集,区间
- HDU 3038 带权并查集,区间
- HDU 3038 带权并查集,区间
- HDU 3038 带权并查集,区间
- 类似区间计数的种类并查集两题--HDU 3038 &amp; POJ 1733
- HDU 3038 带权并查集,区间
- HDU 3038 带权并查集,区间
- HDU 3038 带权并查集,区间
- HDU 3038 How Many Answers Are Wrong (带权并查集+区间判断)
- HDU 3038 带权并查集,区间
- 类似区间计数的种类并查集两题--HDU 3038 & POJ 1733
- HDU 3038 How Many Answers Are Wrong(带权并查集)
- HDU 3038 How Many Answers Are Wrong(并查集)
- hdu 3038 How Many Answers Are Wrong(带权并查集)
- hdu 3038 How Many Answers Are Wrong (种类并查集)
- 带权并查集 - HDU 3038
- D - How Many Answers Are Wrong HDU - 3038(带权并查集)
- hdu 3038 How Many Answers Are Wrong(带权并查集)
- hdu 3038(带权并查集)
- How Many Answers Are Wrong hdu 3038 (带权并查集)