hdu2473 Junk-Mail Filter 並查集的刪除

來源:互聯網
上載者:User

 本題考查的是並查集的刪除.

在刪除結點的時候要注意這樣的問題: 並查集的結構是一棵樹,當把某一個結點刪去(將其父結點置為自己)時,它的子結點的根就會丟失.因此,在刪除某結點的時候,要確定它的所有子結點都已經併到根上了.

解決方案: 為每一個結點加一個虛根,這樣每個結點都是葉子結點.插入結點時,把它們都併到虛根的集合中.刪除結點時,只要把它的父結點置為一個無用的虛根

http://blog.csdn.net/a181551981/article/details/6286007

#include <iostream>   #include <string>   using namespace std;  int n,m,a,b,cnt,father[2000000],s[1000041],ans;  int find(int x);void merge(int x,int y);//固定根節點,n+1~n+n作為根節點,而1~n作為虛擬根節點(指向n+1~n+n),之後在增添n+n~n+n+m作為備用節點   //刪除時直接修改1~n指向的節點到n+n後的節點   int main(){  int Case = 1, n, m, i, a, b, ans;  char ch;while(cin>>n>>m && (n||m)){  for(i = 0; i < n; i++)father[i] = i + n;for(i = n; i < n*2+m;i++)father[i] = i;cnt = 2 * n; ans = 0;memset(s, 0, sizeof(s));while(m--){cin>>ch;if(ch == 'M'){cin>>a>>b;merge(a, b);}else{cin>>a;father[a] = cnt++;}}for(i = 0; i < n; i++){int temp = find(i);if(s[temp] == 0){ans++;s[temp] = 1;}}cout<<"Case #"<<Case<<": "<<ans<<endl;Case++;}  return 0;     }  int find(int x) {    int temp = x,sum = 0,ans;    while(temp != father[temp]) {       temp = father[temp];    }ans = temp;    while(x != ans) {       temp = father[x];       father[x] = ans;       x = temp;    }    return ans;}void merge(int a,int b){int x = find(a);int y = find(b);if(x < y)father[y] = x;else if(x > y)father[x] = y;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.