uva 11987 Almost Union-Find(加權並查集)

來源:互聯網
上載者:User

Problem AAlmost Union-Find

I hope you know the beautiful Union-Find structure. In this problem, you're to implement something similar, but not identical.

The data structure you need to write is also a collection of disjoint sets, supporting 3 operations:

1 p q

Union the sets containing p and q. If p and q are already in the same set, ignore this command.

2 p q

Move p to the set containing q. If p and q are already in the same set, ignore this command

3 p

Return the number of elements and the sum of elements in the set containing p.

Initially, the collection contains n sets: {1}, {2}, {3}, ..., {n}.

Input

There are several test cases. Each test case begins with a line containing two integers n and m (1<=n,m<=100,000), the number of integers, and the number of commands. Each of the next m lines contains a command. For every operation, 1<=p,q<=n. The input
is terminated by end-of-file (EOF). The size of input file does not exceed 5MB.

Output

For each type-3 command, output 2 integers: the number of elements and the sum of elements.

Sample Input
5 71 1 22 3 41 3 53 42 4 13 43 3
Output for the Sample Input
3 123 72 8
Explanation

Initially: {1}, {2}, {3}, {4}, {5}

Collection after operation 1 1 2: {1,2}, {3}, {4}, {5}

Collection after operation 2 3 4: {1,2}, {3,4}, {5} (we omit the empty set that is produced when taking out 3 from {3})

Collection after operation 1 3 5: {1,2}, {3,4,5}

Collection after operation 2 4 1: {1,2,4}, {3,5}

Rujia Liu's Present 3: A Data Structure Contest Celebrating the 100th Anniversary of Tsinghua University
Special Thanks: Yiming Li
Note: Please make sure to test your program with the gift I/O files before submitting!

這題是受luyuncheng的啟發做出來的。

本題的痛點就在2操作:
要把一個元素從一個集合移到另一個集合。
我們知道並查集是不能刪除元素的,因為整個結構是單向的,不知道兒子是什麼
但這裡移動元素,實際上就蘊含著刪除的操作。那該怎麼辦呢?
有一個想法可能會很快想到,並不實際刪除要移動的元素p,即不改變p集合原來的路徑,但集合的權值還是要改變(相當於把p看成一個虛點),然後把p直接“掛到”q的集合中去。
注意,這裡一定要保證p在以後永遠只能作為一個葉子,不能再做父親,否則會覆蓋掉最初(作為父親時)的路徑,並且可以證明只做葉子的做法一定存在。
這樣在寫程式時要注意的就有以下幾點:
1.讓每個元素的值有二維狀態,一維用於儲存,這個元素在最初集合時的情況,另一維儲存這個元素現在實際的情況
2.在合并時注意權值的改變,應該用哪一維狀態。
3.在find()時先判斷這個元素是否真的存在過去和現在兩個狀態,從而選擇搜尋的路徑不同,並且在寫路徑壓縮時也有些不同。

詳見代碼:

#include <cstdio>struct Node{    int fa[2],num[2],value[2];}ele[100005];void init(){    for(int i = 0;i < 100005;i++){        ele[i].fa[0] = i;        ele[i].fa[1] = -1;        ele[i].num[0] = 1;        ele[i].num[1] = 0;        ele[i].value[0] = i;        ele[i].value[1] = 0;    }}int find(int n){    if(ele[n].fa[1] == -1){        int r = ele[n].fa[0];        while(ele[r].fa[0] != r)            r = ele[r].fa[0];        int f = ele[n].fa[0];        while(f != r){            int tem = ele[f].fa[0];            ele[f].fa[0] = r;            f = tem;        }        return r;    }    else{        int f = ele[n].fa[1];        while(ele[f].fa[0] != f){            f = ele[f].fa[0];        }        ele[n].fa[1] = f;        return f;    }}int n,m;int main(){    while(scanf("%d%d",&n,&m) != EOF){        init();        while(m--){            int ope,p,q;            scanf("%d",&ope);            if(ope == 1){                scanf("%d%d",&p,&q);                int f1 = find(p);                int f2 = find(q);                if(f1 != f2){                    ele[f1].fa[0] = f2;                    ele[f2].num[0] += ele[f1].num[0];                    ele[f2].value[0] += ele[f1].value[0];                }            }            else if(ope == 2){                scanf("%d%d",&p,&q);                int f1 = find(p);                int f2 = find(q);//忘了加if(f1 != f2),慢了一些                ele[f1].num[0]--;                ele[f1].value[0] -= p;                ele[p].fa[1] = f2;                ele[f2].num[0]++;                ele[f2].value[0] += p;            }            else{                scanf("%d",&p);                int f = find(p);                printf("%d %d\n",ele[f].num[0],ele[f].value[0]);            }        }    }    return 0;}

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.