POJ 2492[帶權並查集]

A Bug's Life
Time Limit: 10000MS   Memory Limit: 65536K
Total Submissions: 25074   Accepted: 8159

Description

Background 
Professor Hopper is researching the sexual behavior of a rare species of bugs. He assumes that they feature two different genders and that they only interact with bugs of the opposite gender. In his experiment, individual bugs and their interactions were easy to identify, because numbers were printed on their backs. 
Problem 
Given a list of bug interactions, decide whether the experiment supports his assumption of two genders with no homosexual bugs or if it contains some bug interactions that falsify it.

Input

The first line of the input contains the number of scenarios. Each scenario starts with one line giving the number of bugs (at least one, and up to 2000) and the number of interactions (up to 1000000) separated by a single space. In the following lines, each interaction is given in the form of two distinct bug numbers separated by a single space. Bugs are numbered consecutively starting from one.

Output

The output for every scenario is a line containing "Scenario #i:", where i is the number of the scenario starting at 1, followed by one line saying either "No suspicious bugs found!" if the experiment is consistent with his assumption about the bugs' sexual behavior, or "Suspicious bugs found!" if Professor Hopper's assumption is definitely wrong.

Sample Input

2
3 3
1 2
2 3
1 3
4 2
1 2
3 4

Sample Output

Scenario #1:
Suspicious bugs found!

Scenario #2:
No suspicious bugs found!

Hint

Huge input,scanf is recommended.

   題意:

   有T個case,每個case開頭包含N(1到2000)只蟲子和M(1到1000000)個條件關係。每個條件關係都給出a和b,代表a和b可以進行交配,所以屬於不同性別,當給出某條關係a和b是同性別的話,說明兩隻蟲子是同性戀。在給出所有關係後,如果有同性戀,則輸出Suspicious bugs found!如果沒有的話,則輸出No suspicious bugs found!

  

   思路:

   種類並查集,可以用帶權的並查集來做。0代表是同性,1代表的是異性。



轉載自:http://simone-chou.iteye.com/blog/1930207


#include<stdio.h>  
#define max 2000+5  
int root[max],rel[max];  
  
int find(int a)  
{  
    if(root[a]==a) return a;  
    int r=find(root[a]);  
    rel[a]=(rel[a]+rel[root[a]])%2;  
    root[a]=r;  
    return r;  
}  
//找根節點且路徑壓縮  
int main()  
{  
    int n;  
    scanf("%d",&n);  
    for(int j=1;j<=n;j++)  
    {  
        int m,t,temp=0;  
        scanf("%d%d",&m,&t);  
        for(int i=1;i<=m;i++)  
           root[i]=i,rel[i]=0;  
//初始化,一開始自結成樹,都爲同性  
        while(t--)  
        {  
            int a,b;  
            int fa,fb;  
            scanf("%d%d",&a,&b);  
            fa=find(a);  
            fb=find(b);  
            if(fa!=fb)  
            {  
                root[fa]=fb;  
                rel[fa]=(rel[b]+1-rel[a]+2)%2;//只要rel[b]與rel[a]不同,那麼更新a的上級fa爲0,否則爲1  
            }  
            else   
            {  
                if((rel[a]-rel[b]+2)%2==0) temp=1;  //包含了1,1 即兩個均爲異性,和0,0(都是處點)
            }  
//因爲要全部輸完才判斷是不是同性戀  
//所以用temp來標記  
        }  
        printf("Scenario #%d:\n",j);  
        temp?printf("Suspicious bugs found!\n\n"):printf("No suspicious bugs found!\n\n");  
    }  
    return 0;  
}  
以下爲一種思路,轉載自:http://www.cnblogs.com/ACShiryu/archive/2011/09/15/poj2492.html
題目有點怪,就是告訴你有n只蟲子,m條信息,每一條信息的i和j有JQ,求出根據所給的信息能否判斷出有搞基的蟲子,並按照題目要求信息輸出
這題用並查集解決起來很方便,當然搜索也可以解
首先分析第一組數據,則可知1和2異性,2和3也異性,可是1和3竟然也有JQ ,這是怎麼回事?只能說他們在搞基,則輸出Suspicious bugs found!
然後就是這題的處理辦法,首先應該想到的是並查集,對於每一對有JQ的蟲子,可以將他們分入到兩個不同的並查集中,並記錄跟這隻蟲子有JQ的蟲子如果加入後存在衝突,則說明有搞基的蟲子,沒辦法,這樣就可以不用再考慮以後的蟲子JQ了。
上面是大體思路,但有些小細節要考慮
如果那兩隻蟲子之前都沒有對象,都是處蟲,則更新他們的對象信息;
如果只有其中的一個有對象,假設是a,而b沒對象,則將b的對象更新爲a,並且讓a的對象和b同性,也就是入同一個並查集;
如果a和b都有對象,則有兩種情況:
     a和b在同一個並查集裏,則說明a和b有JQ,則可以不必考慮後面的蟲子了;
     否則,將a和b之前的對象入同一個並查集,b和a之前的對象入同一個並查集;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章