hdu 2120 Ice_cream's world I
Ice_cream's world I
Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 483 Accepted Submission(s): 262
Problem Description
ice_cream's world is a rich country, it has many fertile lands. Today, the queen of ice_cream wants award land to diligent ACMers. So there are some watchtowers are set up, and wall between watchtowers be build, in order to partition the ice_cream’s world.
But how many ACMers at most can be awarded by the queen is a big problem. One wall-surrounded land must be given to only one ACMer and no walls are crossed, if you can help the queen solve this problem, you will be get a land.
But how many ACMers at most can be awarded by the queen is a big problem. One wall-surrounded land must be given to only one ACMer and no walls are crossed, if you can help the queen solve this problem, you will be get a land.
Input
In the case, first two integers N, M (N<=1000, M<=10000) is represent the number of watchtower and the number of wall. The watchtower numbered from 0 to N-1. Next following M lines, every line contain two integers A, B mean between A and B has a wall(A and
B are distinct). Terminate by end of file.
B are distinct). Terminate by end of file.
Output
Output the maximum number of ACMers who will be awarded.
One answer one line.
One answer one line.
Sample Input
8 10
0 1
1 2
1 3
2 4
3 4
0 5
5 6
6 7
3 6
4 7
Sample Output
3
Author
Wiskey
Source
Recommend
这道题是并查集判断环数的一个应用。 先说下题意吧,一开始时做这道题题意看了半天才发现自己理解错了..== :将题目抽象出来后的意思大概就是说一开始有n个点,分别编号0~n-1。 然后再给你m条信息格式为a b, 意思为有一条边将点a和点b连接在一起,, 最后问你用这m条线把这n个点连起来后,,会有多少个区域(即多少个环)。
所以,如果能完全理解题意的了话,,这题应该算是并查集里比较裸的题了。 现在就讲下为什么并查集能判环。 .从克鲁斯卡尔这个算法入手;如果学了克鲁斯卡尔的话应该都知道它的生成最小生成树的过程: 每次选取不同属于 同一集合 的 两个集合, 然后将它们合并。 不断地重复这个过程直至将所有点合并在一起后,得到的就是一颗树了。 Note! 这样生成的就是一颗"树",,它是没有任何环的; 在克鲁斯卡尔算法里要用到并查集来判断两个集合两个集合是否同属一起的,, 如果它们是同属同一个集合 而 又把它们合并的话, 就会形成一个环。 所以, 在这题中,, 利用给的m条信息将各个点不断的合并的同时,判断这两个点是否是同属于一个集合,如果不是, 则合并; 否则,环数加一。
AC代码:
1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 #include <cmath> 6 #include <cstdlib> 7 #include <cctype> 8 #include <queue> 9 #include <stack> 10 #include <map> 11 #include <vector> 12 #include <set> 13 #include <utility> 14 typedef long long ll; 15 const int inf=0x3f3f3f3f; 16 using namespace std; 17 18 int a[3000],n,m; 19 void init() //初始化 20 { 21 for(int i=0; i<=n; i++) 22 a[i]=i; 23 } 24 // 25 int father(int v) //寻找父亲结点 26 { 27 if(a[v]==v) return v; 28 return a[v]=father(a[v]); 29 } 30 void unite(int u,int v) //合并 31 { 32 int tu=father(u),tv=father(v); 33 if(tv!=tu) a[tv]=tu; 34 // 35 } 36 int main() 37 { 38 //freopen("input.txt","r",stdin); 39 int u,v; 40 while(scanf("%d%d",&n,&m)!=EOF) 41 { 42 init(); 43 int ans=0; 44 while(m--) 45 { 46 scanf("%d%d",&u,&v); 47 if(father(u)==father(v)) 48 ans++; 49 else 50 unite(u,v); 51 } 52 // 53 printf("%d\n",ans); 54 } 55 return 0; 56 }