http://acm.hdu.edu.cn/showproblem.php?pid=3038
题意:两个小孩(女孩FF,男孩TT)在玩游戏(游戏是给出区间[a, b],算出这个区间的总和是多少),但是FF觉得游戏很无聊,就故意说错了一些值,但是TT很聪明,根据FF的回答可以推论出有的答案是相悖的。现在让你求根据已有答案,可以推论出几条是不正确的。
分析:(不会做,人工百度大神的分析。。。大神的思路不是你想有你就有)
sum[i]表示 i - 根节点的和,求区间和用 sum[b]-sum[a-1],为表示方便,直接让 a--;
向量分析问题:
让b的父亲接在a的父亲上。
1.若 a 和 b 同属一个集合,那么需判断[a, b]区间和是否为s。
if(sum[b] - sum[a] != s) ans++;
2.若 a 和 b 不同属一个集合,把b的父亲接在a的父亲上。
sum[pb] = -sum[b]+s+sum[a];
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <queue> using namespace std; #define maxn 210000 int father[maxn], sum[maxn]; int Find(int x) { if(x!=father[x]) { int k = father[x]; father[x] = Find(father[x]); sum[x] += sum[k]; } return father[x]; } int main() { int n, m, a, b, s; while(scanf("%d %d", &n, &m)!=EOF) { for(int i=0; i<=n; i++) father[i] = i; memset(sum, 0, sizeof(sum)); int ans = 0; while(m --) { scanf("%d %d %d", &a, &b, &s); a--;///求区间和用sum[b]-sum[a-1],为了表示方便,直接a-- int pa = Find(a); int pb = Find(b); if(pa != pb) { father[pb] = pa; sum[pb] = -sum[b]+s+sum[a]; } else { if(sum[b] - sum[a] != s) ans++; } } printf("%d\n", ans); } return 0; }