hdu 1829 A Bug's Life(並查集)


A Bug's Life

Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 364 Accepted Submission(s): 140

Problem 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!

分析:

(1)題意很簡單,就是檢查一堆數據中是否有同性戀,找出主要矛盾是如果1喜歡2,2喜歡3,而1又喜歡3,則矛盾。找出出現類的的矛盾

(2)這里用bugs數組存儲其父親節點的下標,用relation數組存儲該蟲子與根節點之間的關系。1為同性,0為異性。

(3)並查集詳見注釋

#include <stdio.h>
//存儲的是其父親的下表
int bugs[2010];
int relation[2010];//1:相同性別 0:不同性別
//初始化
void init(int len)
{
    for(int i = 0;i <= len; i++)
    {
        bugs[i] = i;
        relation[i] = 1;
    }
}
//找到根
int find(int bug)
{
    if(bugs[bug]==bug)return bug;
    int tem = bugs[bug];
    bugs[bug] = find(bugs[bug]);//遞歸更新域,返回最終的父親節點,把所有的孩子都更新了
    //注意這里,求當前位置和父親的關系,記錄之前父親的位置為tem,然后因為是遞歸,
    //此時的relation[tem]已經在遞歸中更新過了,也就是孩子和父親的關系+父親和爺爺的關系+1然后模2就得到
    //孩子和爺爺的關系,這里用0和1表示,0表示不同性別,1表示相同性別
    relation[bug] = (relation[bug]+relation[tem]+1)%2;
    return bugs[bug];
}

void union_set(int a,int b,int x,int y)
{
    //合並,讓前邊的集合的根指向后邊集合的根,成為一個集合
    bugs[x]=y;
    //更新前邊集合根和新的集合根之間的關系,
    //注意這里,relation[a]+relation[x]與relation[b]
    //相對於新的父節點必須相差1個等級,因為他們不是gay
    relation[x] = (relation[b]-relation[a])%2;
}

int main()
{
    int S;
    int n,inter;
    int bug1,bug2,parent1,parent2;
    bool flag;//false:無同性戀,true:有同性戀
    scanf("%d",&S);
    for(int i=1; i<=S;i++)
    {
        scanf("%d%d",&n,&inter);
        flag = false;
        init(n);//初始化,使其父節點為自己
        for(int j = 1; j <= inter; j++)
        {
            scanf("%d%d",&bug1,&bug2);
            if(flag)continue;
            parent1 = find(bug1);
            parent2 = find(bug2);
            if(parent1==parent2)
            {
                if(relation[bug1]==relation[bug2])//同性
                flag = true;
            }
            union_set(bug1,bug2,parent1,parent2);
        }
        if(flag)
        printf("Scenario #%d:\nSuspicious bugs found!\n",i);
        else
        printf("Scenario #%d:\nNo suspicious bugs found!\n",i);
        printf("\n");
    }
    return 0;
}

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM