7-2 排座位 (25 分)

7-2 排座位 (25 分)

佈置宴席最微妙的事情,就是給前來參宴的各位賓客安排座位。不管如何,總不能把兩個死對頭排到同一張宴會桌旁!這個艱鉅任務如今就交給你,對任何一對客人,請編寫程序告訴主人他們是否能被安排同席。html

輸入格式:

輸入第一行給出3個正整數:N≤100),即前來參宴的賓客總人數,則這些人從1到N編號;M爲已知兩兩賓客之間的關係數;K爲查詢的條數。隨後M行,每行給出一對賓客之間的關係,格式爲:賓客1 賓客2 關係,其中關係爲1表示是朋友,-1表示是死對頭。注意兩我的不可能既是朋友又是敵人。最後K行,每行給出一對須要查詢的賓客編號。數據結構

這裏假設朋友的朋友也是朋友。但敵人的敵人並不必定就是朋友,朋友的敵人也不必定是敵人。只有單純直接的敵對關係纔是絕對不能同席的。spa

輸出格式:

對每一個查詢輸出一行結果:若是兩位賓客之間是朋友,且沒有敵對關係,則輸出No problem;若是他們之間並非朋友,但也不敵對,則輸出OK;若是他們之間有敵對,然而也有共同的朋友,則輸出OK but...;若是他們之間只有敵對關係,則輸出No waycode

輸入樣例:

7 8 4
5 6 1
2 7 -1
1 3 1
3 4 1
6 7 -1
1 2 1
1 4 1
2 3 -1
3 4
5 7
2 3
7 2

  

輸出樣例:

No problem
OK
OK but...
No way

並查集介紹:htm

並查集是一種樹型的數據結構,用於處理一些不相交集合(Disjoint Sets)的合併及查詢問題;blog

經常使用操做有:遞歸

初始化
把每一個點所在集合初始化爲其自身。
一般來講,這個步驟在每次使用該數據結構時只須要執行一次,不管何種實現方式,時間複雜度均爲O(N)。
查找
查找元素所在的集合,即根節點。
合併
將兩個元素所在的集合合併爲一個集合。
一般來講,合併以前,應先判斷兩個元素是否屬於同一集合,這可用上面的「查找」操做實現。
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
int Rela[110][110];//關係
int Parent[110];//上一個節點,同一組的組長的上一節點號爲本身的號
void Init_Parent_Rela(int N)
{
    for(int i=1; i<=N; i++){
        Parent[i] = i;//初始化根節點爲本身 => 並查集的初始化
        for(int j=1; j<=N; j++){
            Rela[i][j] = 0;
            Rela[j][i] = 0;
        }
    }
}
int GetOriNode(int pos)//找根節點,根節點相同則在同一組中 => 並查集的查找
{
    if(Parent[pos] == pos)//若是上一節點號是本身則找到,返回
        return pos;
    else{//不是則遞歸
        int index = GetOriNode(Parent[pos]);
        return index;
    }
}
int Union(int m1, int m2)//=> 並查集的合併
{
    if(GetOriNode(m1) != GetOriNode(m2)){//根節點不一致
        int parent = GetOriNode(m1);//找到m1的根節點
        Parent[parent] = GetOriNode(m2);//將m1的根節點的號改爲m2的根節點號,即將二者劃到同一組
    }
}
int main()
{
    int N, M, K;
    scanf("%d %d %d", &N, &M, &K);
    Init_Parent_Rela(N);
    for(int i=0; i<M; i++){
        int m1, m2, rela;
        scanf("%d %d %d", &m1, &m2, &rela);
        Rela[m1][m2] = rela;
        Rela[m2][m1] = rela;
        if(rela == 1)
            Union(m1, m2);//是朋友就合併朋友圈
    }
    int m1, m2;
    for(int i=0; i<K; i++){
        scanf("%d %d", &m1, &m2);
        if(Rela[m1][m2] == 1)//直接朋友
            printf("No problem\n");
        else if(Rela[m1][m2] == -1){//存在敵對關係
            if(GetOriNode(m1) == GetOriNode(m2))//有共同朋友,在同一朋友圈中
                printf("OK but...\n");
            else//單純的敵對關係
                printf("No way\n");
        }
        else
            printf("OK\n");//不是朋友,我感受不是朋友在統一朋友圈也要輸出"No proble",可是那樣提交錯誤
    }
}
相關文章
相關標籤/搜索