【數據結構】之利用並查集解決食物鏈問題

上一篇我簡單地封裝了一個並查集:【數據結構】之並查集簡易封裝

這次用它來解決一個食物鏈的問題:

/**
 * 食物鏈問題:
 * 有N只動物,編號爲1到N,所有動物都屬於A,B,C中的其中一種。
 * 已知A喫B,B喫C,C喫A。
 * 按順序給出以下兩種信息共K條:
 *  第一種:x和y屬於同一種類。
 *  第二種:x喫y。
 * 然而這些信息可能會出錯:有可能有的信息和之前給出的信息矛盾,
 * 也有可能此信息給出的x或者y不在1到N的範圍裏,請求出錯的信息條數
 */

#include <stdio.h>
#include "union_find.h"
/**
 * 爲了測試方便,就不弄輸入了,直接用以下5行代碼來代表我們所輸入的信息
 * 我們用T,X,Y三個數組來描述這K條信息
 * 拿第一、二條(下標爲0和1)爲例,可以表示爲:
 * 第1種:編號101和編號1屬於同一種類。
 * 第2種:編號1喫編號2。
 */
#define N 100       //有100只動物
#define K 7         //有7條信息
static int T[K] = {  1,2,2,2,1,2,1};  //信息種類,1爲第一種,2爲第二種
static int X[K] = {101,1,2,3,1,3,5};  //信息中的x
static int Y[K] = {  1,2,3,3,3,1,5};  //信息中的y

/**
 * 解題的大體思路
 * 可以用並查集解決這個問題:
 * 在給出信息之前,我們並不知道這100只動物是屬於哪一種類,
 * 因此不妨枚舉出各個動物是3種物種的可能性,建立一個並查集數組data[N*3]
 * 如:data[5],data[5+N],data[5+2*N]分別表示編號5動物分別屬於A,B,C種類
 */
int main() {
    //用於統計錯誤信息數量
    int error_msg_count = 0;
    //創建一個N*3大小的並查集
    UnionFind* uf = new_UnionFind(N * 3);

    for (int i = 0; i < K; ++i) {
        //題目中的編號是從1開始的,可以轉爲從0開始,方便計算
        int x = X[i] - 1;
        int y = Y[i] - 1;
        int type = T[i];
        //超出範圍直接判定爲錯誤信息
        if (x < 0 || y < 0 || x >= N || y >= N){
            error_msg_count++;
            continue;
        }
        //第一種:x和y屬於同一種類
        if (type == 1){
            //當前信息與之前給出的信息相違背的情況
            if (uf->same(uf, x, y+N) || uf->same(uf, x, y+2*N)){
                error_msg_count++;
                continue;
            }
            //沒有矛盾,就合併
            uf->unite(uf, x, y);
            uf->unite(uf, x+N, y+N);
            uf->unite(uf, x+2*N, y+2*N);
        }
        //第二種:x喫y
        else if (type == 2){
            //當前信息與之前給出的信息相違背的情況
            if (uf->same(uf, x, y) || uf->same(uf, x, y+2*N)){
                error_msg_count++;
                continue;
            }
            //沒有矛盾,就合併
            uf->unite(uf, x, y+N);
            uf->unite(uf, x+N, y+2*N);
            uf->unite(uf, x+2*N, y);
        }

    }
    printf("error_msg_count:%d", error_msg_count);
    uf->delete(uf);
    return 0;
}

運行結果:

error_msg_count:3
其中下標爲0,3,4的信息被判定爲錯誤信息

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