并查集

【种类并查集】P2024 [NOI2001]食物链

蹲街弑〆低调 提交于 2019-11-30 21:39:47
1 #include<iostream> 2 using namespace std; 3 4 int fa[150010]; 5 int n, k; 6 int cnt; 7 8 int find(int x) 9 { 10 if (x == fa[x]) return x; 11 fa[x] = find(fa[x]); 12 return fa[x]; 13 } 14 15 void merge1(int a, int b) 16 { 17 fa[find(a)] = find(b); 18 fa[find(a + n)] = find(b + n); 19 fa[find(a + n * 2)] = find(b + n * 2); 20 } 21 22 void merge2(int a, int b) 23 { 24 fa[find(a)] = find(b + n + n); 25 fa[find(a + n)] = find(b); 26 fa[find(a + n + n)] = find(b + n); 27 } 28 29 struct Edge 30 { 31 int u, v; 32 }e[100010]; 33 34 int main() 35 { 36 cin >> n >> k; 37 for (int i = 1; i <= n * 3; i++)

P3367 【模板】并查集

∥☆過路亽.° 提交于 2019-11-30 21:38:38
1 #include<iostream> 2 using namespace std; 3 int b[10010]; 4 5 int find(int n) 6 { 7 if (b[n] == n) return n; 8 return b[n] = find(b[n]); 9 } 10 int main() 11 { 12 int n, m; 13 cin >> n >> m; 14 for (int i = 1; i <= n; i++) b[i] = i; 15 int p1, p2, p3; 16 for (int i = 1; i <= m; i++) 17 { 18 cin >> p1 >> p2 >> p3; 19 if (p1 == 1) b[find(p2)] = find(p3); 20 else if (find(p2) == find(p3)) cout << "Y" << endl; 21 else cout << "N" << endl; 22 } 23 } View Code 来源: https://www.cnblogs.com/thjkhdf12/p/11641332.html

并查集 || [USACO18JAN]MooTube || BZOJ 5188 || Luogu P4185

岁酱吖の 提交于 2019-11-30 16:41:28
题面: [USACO18JAN]MooTube 题解: 对边和询问都排序,然后每次把符合当前要求的边都扔并查集里,对于每个询问判断当前并查集里节点数即可。 我很无聊地给并查集加了按秩排序,还开了O2,加了快读,也才170ms,虽然在第一面,然鹅还是没有办法排太前。 上述操作都不做也行 代码: 1 #include<cstdio> 2 #include<algorithm> 3 using namespace std; 4 inline int rd(){ 5 int x=0; char c=getchar(); 6 while(c<'0'||c>'9')c=getchar(); 7 while(c>='0'&&c<='9'){x=x*10+c-'0'; c=getchar();} 8 return x; 9 } 10 const int maxn=1e5+5,maxq=1e5+5; 11 int N,Q,a,b,c,fa[maxn],dep[maxn],f1,f2,now,cnt[maxn],ans[maxq]; 12 struct Edge{ int from,to,dis; }edge[maxn]; 13 struct Query_{ int k,x,id; }qry[maxq]; 14 inline bool cmp1(const Edge&a,const Edge&b){

Wireless Network POJ - 2236 并查集 坐标点的转换

帅比萌擦擦* 提交于 2019-11-30 12:30:28
An earthquake takes place in Southeast Asia. The ACM (Asia Cooperated Medical team) have set up a wireless network with the lap computers, but an unexpected aftershock attacked, all computers in the network were all broken. The computers are repaired one by one, and the network gradually began to work again. Because of the hardware restricts, each computer can only directly communicate with the computers that are not farther than d meters from it. But every computer can be regarded as the intermediary of the communication between two other computers, that is to say computer A and computer B

并查集

橙三吉。 提交于 2019-11-30 12:20:53
package newcoder; import java.util.HashMap; import java.util.List; import java.util.Stack; public class UnionFind { public static class Element<V> { public V value; public Element (V value) { this.value = value; } } public static class UnionFindSet<V> { /** * 根据用户的value映射为包装类 */ public HashMap<V, Element<V>> elementMap; /** * 每个element都有自己的parent,代表节点的parent为自己 */ public HashMap<Element<V>, Element<V>> parentMap; /** * 每个代表节点代表了多少节点(如果不是代表节点,则为0) */ public HashMap<Element<V>, Integer> sizeMap; /** * 初始化操作 */ public UnionFindSet(List<V> list) { elementMap = new HashMap<>(); parentMap = new

「带权并查集」食物链

会有一股神秘感。 提交于 2019-11-30 09:44:36
食物链 原题链接: 食物链 题目大意 给你N组数,每组数由三个数构成,如果第一个数是1,那么就说明后面两个数代表的物体是同类,如果第一个数是2,那么就代表第二个数吃第三个数,现在问你说假话的总数 题目题解 这个题作为带权并查集中的 “拓展域” 的模板题只能说过于经典,比上一道题简单,我们可以很简单的得到这道题的逻辑关系 我们需要将一个节点拆成三份,分别表示 同类域,捕食域,天敌域 ,那么就可以得到以下逻辑关系 若x, y是同类,那么他们的同类域、捕食域、天敌域相同,就合并 若x吃y,那么x的捕食域要加上y,y的天敌域要加上x,同理 x的同类域的捕食域也要加上y,y的同类域的天敌域也要加上x 又因为题目所说食物链是长度为3的环,那么 x的天敌域就是y的捕食域 若y吃x 与上面同理 如何判断是 x与y是同类 矛盾 x的捕食域和y的同类域在同一集合,说明x 吃 y x的同类域和y的捕食域在同一集合,说明y 吃 x 如何判断是 x吃y 矛盾 x的同类域和y的同类域在同一集合,说明x y是同类 x的同类域和y的捕食域在同一集合,说明y 吃 x 通过以上信息,我们就能够得到代码如下 //#define fre yes #include <cstdio> int n, k; const int N = 50005; namespace Union { int par[N << 2];

9.21 生成树

瘦欲@ 提交于 2019-11-30 06:17:58
题意 给定一颗边带权树,求出对于每一条边来说,在保证其出现在最小生成树上的同时,它可能具有的最大边权 若最大边权可以为无限大,输出 \(10^9\) 解法 考试时暴力跳链跳了 \(98pts\) ,啊哈哈 首先把最小生成树跑出来,对于每一个非树边,它的答案是其覆盖的树边的边权的最大值;因为这条非树边是可以代替其覆盖的树边中的任意一个的 而对于每一个树边来说,它的答案是所有覆盖它的非树边的边权的最小值,因为这样它既能保证其本身的权值最大又不至于被其他非树边所替代 我们把非树边按边权从小到大排序(实际上由于求的是最小生成树,可以没必要排序) 由于边权已经是从小到大了,所以一个边的答案会由更新它的第一条非树边确定 我们每次在更新完一条非树边覆盖的边的答案时,就用并查集把它们缩起来,避免下次重复遍历到答案已经确定的边;把并查集的根设为深度最小的点 之后的修改操作直接跳到该并查集的根,也就确定了第一个没有被修改的边 至于非树边的答案,倍增求一下即可 复杂度是 \(O(N \log N)\) 的(如果不管并查集的 \(\alpha\) 的话) 代码 来源: https://www.cnblogs.com/VeniVidiVici/p/11566921.html

C - Justice(优先队列+并查集)

杀马特。学长 韩版系。学妹 提交于 2019-11-30 06:07:45
Put simply, the Justice card represents justice, fairness, truth and the law. You are being called to account for your actions and will be judged accordingly. If you have acted in a way that is in alignment with your Higher Self and for the greater good of others, you have nothing to worry about. However, if you have acted in a way that is out of alignment, you will be called out and required to own up to your actions. If this has you shaking in your boots, know that the Justice card isn’t as black and white as you may think. On the table there are n weights. On the body of the i-th weight

区间 (模拟并查集优化)

家住魔仙堡 提交于 2019-11-30 05:54:09
问题描述 给出一个序列 a1, ..., an。 定义一个区间 [l,r] 是好的,当且仅当这个区间中存在一个 i,使得 ai 恰好等于 al, al+1, ..., ar-1, ar 的最大公因数。 求最长的好的区间的长度。 输入 第一行 n,表示序列的长度; 第二行 n 个数 a1,a2,...,an。 输出 输出一行一个数,表示最长的好的区间的长度。 题解 题解写代码里可能容易懂? 代码 #include <cstdio> #define ll long long #define file(x) freopen(x".in","r",stdin);freopen(x".out","w",stdout); using namespace std; inline ll read(){ ll x=0,f=1;char c=getchar(); while (c>'9'||c<'0') {if (c=='-') f=-1;c=getchar();} while (c>='0'&&c<='9') {x=(x<<1)+(x<<3)+(c^48);c=getchar();} return x*f; } const int maxn(4e6+5); ll n,a[maxn],l[maxn],r[maxn],ans; void init(){ n=read(); for (int i(1);i

[cf1217F]Forced Online Queries Problem

感情迁移 提交于 2019-11-30 05:04:45
可以用并查集维护连通性,删除可以用按置合并并查集,但删掉一条边后无法再维护两点的联通性了(因为产生环的边是不加入的) 暴力思路是, 考虑前i个操作后边的集合,暴力加入即可,但复杂度是$o(n^2)$的 用分块,对于每一个块,先求出前面所有块操作后边的集合,去掉这个块内删掉的边,这个并查集一定是之后这个块内每一个点都有的并查集,即计算每一个点时都恢复到这个并查集(恢复时记录下修改的点,因此也不能路径压缩) 之后用暴力的做法,这个集合大小是$o(\sqrt{n})$的,那么总复杂度就是$o(n\sqrt{n})$,可以通过 (这个算法是离线,因为它需要之后那个块内的操作,但这些操作最多只会衍生出两种操作,只要存在一个就都不要放入原并查集中即可) 1 #include<bits/stdc++.h> 2 using namespace std; 3 #define K 5000 4 #define N 200005 5 #define pii pair<int,int> 6 #define fi first 7 #define se second 8 int n,m,ans,p[N],x[N],y[N],f[N],g[N],sz[N],v1[N]; 9 pii v2[N]; 10 set<pii>g1,g2; 11 set<pii>::iterator it; 12 int find