swjtuoj2433 Magic Mirror
Magic Mirror is an artificial intelligence system developed by TAL AI LAB,It can determine human based on human bone information.
Meternal use the magic mirror API,then he found after he input some photo to the system,it will output the two endpoint features of each bone of the human body.
a bone can be described by a integer pair like (1,2) represent this bone consists of endpoint 1 and endpoint 2 .
We can think that everyone’s bones endpoint features are unique.
But when using the magic mirror‘s API, Meternal broke all the order, and now you need to help him determine the endpoint features that each person has.
The system may contain some unused information which never included in any bone,please skip them.
The data contains n types of endpoints and m bones which described by a pair.
The first line contains two integer n(1≤n≤200000) and m(1≤m≤200000) ,the number of endpoint and bones.
The following m lines,
each line contains two integer a(1≤a≤n) and b(1≤b≤n),the features of two endpoint of this bone.
The output contains some lines of bone endpoint information.
Please output the information of each person in according order by the smallest endpoint number of this person.
For the i-th line information first outputs the number k, the endpoint contained by this person.
then outputs k endpoint number in ascending order.
When the output is complete, output a line "Finish".
please skip unused endpoint.
6 4
1 3
2 5
3 3
3 4
3 1 3 4
2 2 5
Finish
==========================================================================================================
思路:本題考查查並集的基本操作,輸出時要求一個集合一個集合輸出,集合內的輸出順序為從小到大,集合間的順序以集合最小元素按升序輸出。
可選用vector來存儲一個集合,將元素從小到大遍歷,每找到一個未輸出的集合,便找到相應的vector輸出裏面的全部元素。最後一行輸出Finish。
註意點:
- 直接暴力搜索每一個元素會超時,將每個集合放在一起可避免無效搜索。
- 兩個根節點相同時合並時,會出現錯誤,不要忘記在合並前判定其根節點是否相等。
1 #include<stdio.h> 2 #include<vector> 3 using namespace std; 4 5 const int Maxn = 200005; 6 int set[Maxn]; 7 vector<int> ans[Maxn]; 8 int sign[Maxn]; 9 void init(){ 10 for(int i = 0; i < Maxn; i++){ 11 set[i] = -1; 12 } 13 14 } 15 16 int Find(int d1){ 17 if(set[d1] < 0){ 18 return d1; 19 } 20 set[d1] = Find(set[d1]); //路徑壓縮 21 return set[d1]; 22 } 23 24 void Union(int d1,int d2){ 25 int root1 = Find(d1); 26 int root2 = Find(d2); 27 if(root1==root2){ 28 return; 29 } 30 if(set[root1] > set[root2]){ //按秩歸並 31 set[root2] += set[root1]; 32 set[root1] = root2; 33 }else{ 34 set[root1] += set[root2]; 35 set[root2] = root1; 36 } 37 return ; 38 } 39 40 41 int main(){ 42 init(); 43 int n,m; 44 scanf("%d %d",&n,&m); 45 while(m--){ 46 int d1,d2; 47 scanf("%d %d",&d1,&d2); 48 Union(d1,d2); 49 } 50 51 for(int i = 1; i < Maxn; i++){ 52 ans[Find(i)].push_back(i); 53 54 } 55 for(int i = 1; i < Maxn ; i++){ 56 if(sign[Find(i)] == 1||set[Find(i)] > -2){ 57 continue; 58 } 59 sign[Find(i)] = 1; 60 printf("%d", -set[Find(i)]); 61 for(int j = 0; j < ans[Find(i)].size();j++){ 62 printf(" %d",ans[Find(i)][j]); 63 } 64 printf("\n"); 65 } 66 printf("Finish"); 67 }
swjtuoj2433 Magic Mirror