并查集

POJ 1989(双权值并查集)

ぐ巨炮叔叔 提交于 2019-11-28 13:52:26
Navigation Nightmare Time Limit: 2000MS Memory Limit: 30000K Total Submissions: 8503 Accepted: 3062 Case Time Limit: 1000MS Description Farmer John's pastoral neighborhood has N farms (2 <= N <= 40,000), usually numbered/labeled 1..N. A series of M (1 <= M < 40,000) vertical and horizontal roads each of varying lengths (1 <= length <= 1000) connect the farms. A map of these farms might look something like the illustration below in which farms are labeled F1..F7 for clarity and lengths between connected farms are shown as (n): F1 --- (13) ---- F6 --- (9) ----- F3 | | (3) | | (7) F4 --- (20) ---

POJ 1182(权值并查集,向量?)

风格不统一 提交于 2019-11-28 12:35:03
食物链 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 108628 Accepted: 32960 Description 动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形。A吃B, B吃C,C吃A。 现有N个动物,以1-N编号。每个动物都是A,B,C中的一种,但是我们并不知道它到底是哪一种。 有人用两种说法对这N个动物所构成的食物链关系进行描述: 第一种说法是"1 X Y",表示X和Y是同类。 第二种说法是"2 X Y",表示X吃Y。 此人对N个动物,用上述两种说法,一句接一句地说出K句话,这K句话有的是真的,有的是假的。当一句话满足下列三条之一时,这句话就是假话,否则就是真话。 1) 当前的话与前面的某些真的话冲突,就是假话; 2) 当前的话中X或Y比N大,就是假话; 3) 当前的话表示X吃X,就是假话。 你的任务是根据给定的N(1 <= N <= 50,000)和K句话(0 <= K <= 100,000),输出假话的总数。 Input 第一行是两个整数N和K,以一个空格分隔。 以下K行每行是三个正整数 D,X,Y,两数之间用一个空格隔开,其中D表示说法的种类。 若D=1,则表示X和Y是同类。 若D=2,则表示X吃Y。 Output 只有一个整数,表示假话的数目。 Sample

洛谷P2024 [NOI2001]食物链

你。 提交于 2019-11-28 12:29:38
题目描述 动物王国中有三类动物 A,B,C,这三类动物的食物链构成了有趣的环形。A 吃 B,B 吃 C,C 吃 A。 现有 N 个动物,以 1 - N 编号。每个动物都是 A,B,C 中的一种,但是我们并不知道 它到底是哪一种。 有人用两种说法对这 N 个动物所构成的食物链关系进行描述: 第一种说法是“1 X Y”,表示 X 和 Y 是同类。 第二种说法是“2 X Y”,表示 X 吃 Y 。 此人对 N 个动物,用上述两种说法,一句接一句地说出 K 句话,这 K 句话有的是真 的,有的是假的。当一句话满足下列三条之一时,这句话就是假话,否则就是真话。 • 当前的话与前面的某些真的话冲突,就是假话 • 当前的话中 X 或 Y 比 N 大,就是假话 • 当前的话表示 X 吃 X,就是假话 你的任务是根据给定的 N 和 K 句话,输出假话的总数。 输入格式 从 eat.in 中输入数据 第一行两个整数,N,K,表示有 N 个动物,K 句话。 第二行开始每行一句话(按照题目要求,见样例) 输出格式 输出到 eat.out 中 一行,一个整数,表示假话的总数。 苦涩地写这篇题解…,这道题我做了五个小时,原因竟是,我把题干中最重要的一句话当成了废话555。 题目背景中写道“动物王国中有三类动物 A,B,C,这三类动物的食物链构成了有趣的环形。A 吃 B,B 吃 C,C 吃 A。

POJ-1182(经典带权并查集)

丶灬走出姿态 提交于 2019-11-28 12:15:16
食物链 POJ-1182 一个很好的分析博客: https://blog.csdn.net/niushuai666/article/details/6981689 三种关系:两者同类,吃父节点,被父节点吃,所以权值可以用0,1,2表示 #include<iostream> #include<cstring> #include<cstdio> #include<string> #include<algorithm> #include<cmath> #include<vector> #include<map> using namespace std; const int maxn=50004; int n,m; int set[maxn]; int sum[maxn]; int ans; int find(int x){ if(x==set[x]) return set[x]; else{ int parent=set[x]; set[x]=find(set[x]); sum[x]=(sum[x]+sum[parent])%3; return set[x]; } } void merge(int type,int a,int b){ int ta=find(a); int tb=find(b); if(ta==tb){ if((sum[a]-sum[b]+3)%3!=type-1)

HDOJ-3038(带权并查集)

我们两清 提交于 2019-11-28 11:09:18
How many answers wrong HDOJ-3038 一个很好的博客: https://www.cnblogs.com/liyinggang/p/5327055.html #include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> #include<cmath> using namespace std; const int maxn=200004; int n,m; int set[maxn]; int sum[200004]; int ans; int find(int x){ if(x==set[x]) return set[x]; else{ int parent=set[x]; set[x]=find(set[x]); sum[x]+=sum[parent]; return set[x]; } } void merge(int a,int b,int w){ a--; int ta=find(a); int tb=find(b); if(ta==tb){ if(sum[a]-sum[b]!=w) ans++; }else{ set[ta]=tb; sum[ta]=sum[b]-sum[a]+w; } } int main(){ while

HDOJ-1213(简单并查集)

佐手、 提交于 2019-11-28 10:59:14
How many tables HDOJ-1213 #include<iostream> #include<cstring> #include<cstdio> #include<string> #include<algorithm> #include<cmath> #include<vector> #include<map> using namespace std; const int maxn=1004; int n,m; int set[maxn]; int rank1[maxn];//rank1[i]表示i的深度 int find(int x){ if(x==set[x]) return set[x]; return set[x]=find(set[x]); } void merge(int a,int b){ int ta=find(a); int tb=find(b); if(ta!=tb){ if(rank1[ta]<rank1[tb]){ set[ta]=tb; }else{ set[tb]=ta; if(rank1[ta]==rank1[tb]){ rank1[ta]++; } } }else return; } int main(){ int t; cin>>t; while(t--){ cin>>n>>m; for(int i=1;i<=n;i++){ set

POJ-1611(并查集)

我是研究僧i 提交于 2019-11-28 10:58:37
The Suspects POJ-1611 这题就是并查集的简单应用 #include<iostream> #include<cstring> #include<cstdio> #include<string> #include<algorithm> #include<cmath> #include<vector> #include<map> using namespace std; const int maxn=30004; int n,m; int set[maxn]; int rank1[maxn];//rank1[i]表示i的深度 map<int,int> stu; int find(int x){ if(x==set[x]) return set[x]; return set[x]=find(set[x]); } void merge(int a,int b){ int ta=find(a); int tb=find(b); if(ta!=tb){ if(rank1[ta]<rank1[tb]){ set[ta]=tb; }else{ set[tb]=ta; if(rank1[ta]==rank1[tb]){ rank1[ta]++; } } }else return; } vector<int> group[505]; int main(){ ios::sync

POJ-2236(并查集)

☆樱花仙子☆ 提交于 2019-11-28 10:55:34
Wireless NetWork POJ-2236 需要注意这里的树的深度需要初始化为0。 而且,find函数需要使用路径压缩,这里的unint合并函数也使用了优化(用一开始简单的合并过不了)。 #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<string> #include<cmath> using namespace std; int n,d; bool repaired[1002]; struct node{ int x; int y; }; node com[1002]; int set[1002]; int rank1[1002];//rank1[i]表示i的深度 int find(int x){ if(x==set[x]) return set[x]; return set[x]=find(set[x]); } void unint(int a,int b){ int ta=find(a); int tb=find(b); if(ta!=tb){ if(rank1[ta]<rank1[tb]){ set[ta]=tb; }else{ set[tb]=ta; if(rank1[ta]==rank1[tb]){ rank1[ta]++; } } }else

HDU 3038(权值并查集)

本小妞迷上赌 提交于 2019-11-28 10:54:57
How Many Answers Are Wrong Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 21469 Accepted Submission(s): 7404 Problem Description TT and FF are ... friends. Uh... very very good friends -________-b FF is a bad boy, he is always wooing TT to play the following game with him. This is a very humdrum game. To begin with, TT should write down a sequence of integers-_-!!(bored). Then, FF can choose a continuous subsequence from it(for example the subsequence from the third to the fifth integer inclusively). After that, FF will ask TT what the sum

树上乱搞(树上数据结构

二次信任 提交于 2019-11-28 10:51:38
树上乱搞 bzoj3319:黑白树 做这题之前我们先体验一个 水题 , 一个 离线就变得容易的题 (WTM因为没有倒着输出而改了好些时间...傻子 bzoj4551: [Tjoi2016&Heoi2016]树 Description 在2016年,佳媛姐姐刚刚学习了树,非常开心。现在他想解决这样一个问题:给定一颗有根树(根为1),有以下 两种操作:1. 标记操作:对某个结点打上标记(在最开始,只有结点1有标记,其他结点均无标记,而且对于某个 结点,可以打多次标记。)2. 询问操作:询问某个结点最近的一个打了标记的祖先(这个结点本身也算自己的祖 先)你能帮帮他吗? 分析 显然,可以用线段树+树剖暴力在线做 再想想,没必要这样,因为它维护的信息太简单了,所以,这时候就想到了离线.. 太牵强了吧 (因为重点不在这,所以我们直接看黑白树吧....还是放上代码吧 #include<cstdio> #include<algorithm> #include<iostream> using namespace std; const int MAX = 100000+99; int n,m; int stck[MAX]; int father[MAX]; int fa[MAX], cont[MAX]; int find(int x) { if(x == fa[x]) return x; return