并查集的实战使用(绵羊趣题)
上一篇文章,我抄了讲了并查集的基本使用,这一次,我搞定了南外的一道绵羊趣题,当中用到了并查集。
话不多说,上题目和代码!
并查集趣题
抓羊
(存盘文件名为csheep.pas/c/cpp)
时间限制:1 sec 内存限制:128 MB
题目描述
老江带着hh和南瓜搞不好到内蒙古旅游,在野外老江想晚上吃烧全羊,于是他命令hh和南瓜搞不好去抓羊。他们俩来到一个地方见到茫茫多的野羊,他们给野羊标号为1..N。他们决定用若干条绳子将野羊相互连接起来带给老江。当然,任意两头野羊之间只有一根绳子直接连接。输入显示野羊c1 和野羊 c2是已经连着的。
hh与南瓜搞不好将野羊们相互连在一起而且其中要有1号野羊(野羊首领,不然羊们带不走)。但南瓜搞不好用绳子绑羊时“见羊就绑”,不论是不是与1号野羊在一起!绑完后,hh急了,想找出不符合要求的野羊,于是用程序找出(升序)没有直接或间接连到1号羊的野羊编号(当然,1号野羊显然与自己相连)。假如所有野羊都符合要求,则输出0。
下面的例子中,有6头野羊,4根绳子:
1---2 4---5
\ |
\ | 6
\|
3
显然,4号野羊、5号野羊、6号野羊没有直接或间接与1号羊相连。
请你也用程序找出不符合要求的野羊。
输入格式
第1行:两个用空格隔开的整数: N 与M (1≤N≤300,000,1≤ M≤600,000)其中N代表野羊的只数,M代表绑羊的绳子数。
第2..M+1行:第i+1行有两个用空格隔开的整数c1和c2,表示野羊c1和野羊c2有绳直接相连 (1≤c1 ≤N; 1≤c2≤ N; c1≠c2)
输出格式
输出不符合要求的野羊的序号(升序)。
样例
csheep.in 6 4 1 3 2 3 1 2 4 5 |
csheep.out 4 5 6
|
数据规模
对于全部的数据,有50%测试数据N≤10,000;
对于全部的数据,有100%测试数据N≤300,000.
原创代码
1 #include<bits/stdc++.h> 2 using namespace std; 3 int i,k,n,m,f[300000],p1,p2; 4 int find(int k)//定义find函数 5 { 6 if(f[k]==k)return k; 7 return f[k]=find(f[k]); 8 } 9 int main() 10 { 11 freopen("csheep.in","r",stdin);//输入文件操作,不需要可以注释掉 12 freopen("csheep.out","w",stdout);//输出文件操作 ,不需要可以注释掉 13 cin>>n>>m; //输入绵羊的数量,绳子的数量 14 for(i=1;i<=n;i++) 15 { 16 f[i]=i;//初始化,每只羊都自己绑着自己 17 } 18 for(i=1;i<=m;i++) 19 { 20 cin>>p1>>p2;//重复输入,互相绑住的羊A和羊B 21 f[find(p1)]=find(p2);//记录:羊A绑住了羊B 22 } 23 for(i=1;i<=n;i++) 24 { 25 if(find(1)!=find(i))//反复判断,如果该羊最终没有和羊1绑住 26 { 27 cout<<i<<endl;//就输出它的编号 28 } 29 } 30 return 0; 31 }
这就是并查集趣题之抓羊,喜欢请支持。