1202: [HNOI2005]狡猾的商人
2018-10-08 16:34
204 查看
1202: [HNOI2005]狡猾的商人
https://www.lydsy.com/JudgeOnline/problem.php?id=1202
带权并查集。
/* 带权并查集! 首先可以把每个月抽象一个点,那么知道了a~b,a~c月的收入,相当于知道了a->b,a->c的距离。 如果再知道b~c的收入,那么就可以判断了。对应图上,相当于找到了环,判断b->c的距离是否等于a->c的距离减去a->b的距离。 a->b->c 于是并查集的功能就是找环,其次还要维护这些的距离关系。 如何维护距离?——带权并查集。 考虑每个点x附加一个值val[x]=s[x]-s[g],g为并查集的根,s为1~x的前缀和。 查询: 当前l(l默认已经减一),r已经是同一个并查集了。 查询s[r]-s[l],就是val[l]=s[l]-s[g],val[r]=s[r]-s[g],就是val[r]-val[l]=s[r]-s[l],s[g]约掉了。 合并: 新加入两个点l,r,长度为w,如果l,r已经是一个并查集,跳过。 否则,设u为l的根,v为r的根(下面默认让v为合并后的并查集的根),那么v的子树是不用变动的。 对于u的子树,先考虑u:当前val[u]=s[u]-s[u]=0,合并后val[u]=s[u]-s[v]。 正推:由val[l]=s[l]-s[u],s[u]=val[l]+s[l],同理s[v]=val[r]+s[r] s[u]-s[v]=val[r]-val[l]+s[r]-s[l]=val[r]-val[l]+w; 逆推:val[l]=s[l]-s[u],val[r]=s[r]-s[v],那么用后面的减前面的得: var[r]-val[l]=s[r]-s[l]+s[u]-s[v]=w+s[u]-s[v] val[r]-val[l]-w=s[u]-s[v]; 于是求出val[u]。 对于其他的u的子节点x,在路径压缩后,它们同样是连向v,对于x,其父节点u(并查集只有一层,即使还没有进行路径压缩,它的父节点一定是类似u的点,已更新) val[u]=s[u]-s[v],当前val[x]=s[x]-s[u] val[x]+val[u]=s[x]-s[u]+s[u]-s[v]=s[x]-s[v]; */ #include<bits/stdc++.h> using namespace std; typedef long long LL; inline int read() { int x=0,f=1;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-1; for (;isdigit(ch);ch=getchar())x=x*10+ch-'0';return x*f; } const int N = 1010; int fa ,val ; int find(int x) { if (x == fa[x]) return x; int tmp = find(fa[x]); val[x] += val[fa[x]]; fa[x] = tmp; return fa[x]; } inline void work() { int n = read(),m = read(); for (int i=0; i<=n; ++i) { fa[i] = i,val[i] = 0; } bool flag = true; for (int i=1; i<=m; ++i) { int l = read(),r = read(),w = read(); l --; int u = find(l),v = find(r); if (u != v) { fa[u] = v; val[u] = val[r] - val[l] + w; } else if (val[l] - val[r] != w) flag = false; } puts(flag?"true":"false"); } int main() { int Case = read(); while (Case--) work(); return 0; }
相关文章推荐
- [BZOJ1202][HNOI2005][差分约束]狡猾的商人[水题]
- 【BZOJ1202】[HNOI2005]狡猾的商人 带权并查集
- BZOJ 1202: [HNOI2005]狡猾的商人(并查集)
- BZOJ 1202 [HNOI2005]狡猾的商人
- 【BZOJ1202】【HNOI2005】狡猾的商人
- BZOJ 1202: [HNOI2005]狡猾的商人 并查集
- BZOJ1202 [HNOI2005]狡猾的商人&&BZOJ3436小K的农场
- 【bzoj1202】[HNOI2005]狡猾的商人 带权并查集
- bzoj 1202 [HNOI2005]狡猾的商人
- 【BZOJ1202】【HNOI2005】狡猾的商人
- bzoj 1202: [HNOI2005]狡猾的商人
- 1202: [HNOI2005]狡猾的商人 - BZOJ
- 【BZOJ 1202】【HNOI 2005】 狡猾的商人
- [bzoj1202][HNOI2005]狡猾的商人[并查集]
- [BZOJ1202][HNOI2005]狡猾的商人
- BZOJ 1202 [HNOI2005]狡猾的商人(并查集)
- (bzoj 1202: [HNOI2005]狡猾的商人)<并查集>
- [HNOI2005][BZOJ1202] 狡猾的商人
- bzoj1202 [HNOI2005]狡猾的商人 (带权并查集)
- bzoj1202: [HNOI2005]狡猾的商人(带权并查集)