poj 2513(trie樹+並查集+歐拉回路條件)(記得要初始化指針數組)

Colored Sticks
Time Limit: 5000MS   Memory Limit: 128000K
Total Submissions: 28302   Accepted: 7481

Description

You are given a bunch of wooden sticks. Each endpoint of each stick is colored with some color. Is it possible to align the sticks in a straight line such that the colors of the endpoints that touch are of the same color?

Input

Input is a sequence of lines, each line contains two words, separated by spaces, giving the colors of the endpoints of one stick. A word is a sequence of lowercase letters no longer than 10 characters. There is no more than 250000 sticks.

Output

If the sticks can be aligned in the desired way, output a single line saying Possible, otherwise output Impossible.

Sample Input

blue red
red violet
cyan blue
blue magenta
magenta cyan

Sample Output

Possible

Hint

Huge input,scanf is recommended.

Source

The UofA Local 2000.10.14

非常沮喪的 RE 多次。
trie樹用鏈表來實現吧:
結構體中的 next指針用來尋找下一個字母node。
isdict變量表示這個結點是不是一個詞典中的單詞。(必須有!)
struct node {
    node * next[26];
    bool isdict;
};

然後遍歷輸入串,在樹上行走。發現NULL指針就new一個。一定要注意new後要把新結點的next指針都初始化爲NULL。否則可能是野指針,導致RE。
    while(s[i]) {
        int a = s[i] - 'a';
        assert(a < 26);
        if (cur->next[a] == NULL) {
            cur->next[a] = new node;
            memset(cur->next[a]->next, NULL, sizeof(cur->next[a]->next));
            cur->next[a]->f = false;
        }   
        cur = cur->next[a];
        i++;
    }   

首先要判斷圖的聯通(用並查集後,所有點的root相同)
其次要判斷入度爲奇數的點,或者爲0,或者爲2。
以上兩個條件都滿足時,則必存在歐拉回路,否則必不存在歐拉回路。


提交記錄:
1-N、RE。 記得要初始化指針。否則結果不可預知。
N+1、AC。

/*Source Code
Problem: 2513		User: 775700879
Memory: 87916K		Time: 1391MS
Language: G++		Result: Accepted

    Source Code*/

    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #define oo 0x3f3f3f3f
    #define N 1000000 
    using namespace std;
    int icount[N];
    int par[N];
    int rank[N];
    int color_num = 0;
    struct node {
        bool f;
        int num;
        struct node * next[30];
    };
    node * head = new node;
    int find(int a) {
        int x = par[a];
        if (x == a) return x;
        else return par[a] = find(x);
    }
    void unite(int a, int b) {
        int x = find(a);
        int y = find(b);
        if (x == y) return ;
        if (rank[x] < rank[y]) {
            par[x] = y;
        }
        else {
            par[y] = x;
            if (rank[x] == rank[y]) rank[x] ++;
        }
    }
    int find_num(char s[]) {
        int i = 0;
        node * cur = head;
        while(s[i]) {
            int a = s[i] - 'a';
            assert(a < 26);
            if (cur->next[a] == NULL) {
                cur->next[a] = new node;
                memset(cur->next[a]->next, NULL, sizeof(cur->next[a]->next));
                cur->next[a]->f = false;
            }
            cur = cur->next[a];
            i++;
        }
        if (cur->f == false) {
            cur->f = true;
            cur->num = color_num++;
        }
        return cur->num;
    }
    int main() {
        char a[30], b[30];
        int i, j, k;
        int numa, numb;
        for (i = 0; i < N; i++) {par[i] = i; rank[i] = 0;}
        memset(head->next, NULL, sizeof(head->next));
        while (EOF != scanf("%s%s", a, b)) {
            numa = find_num(a);    
            numb = find_num(b);
            assert(numa < N);
            assert(numb < N);
            icount[numa]++;
            icount[numb]++;
            unite(numa, numb);
        }
        bool flag = true;
        int num = 0;
        if (color_num >= N) return 0;
        for (i = 0; i < color_num; i++) {
            if (icount[i] % 2 != 0) num++; 
            if (num > 2) {
                flag = false;
                break;
            }
        }
        if (num == 1) flag = false;
        if (flag) {
            int root = par[0];
            for (i = 0; i < color_num; i++) {
                if (par[i] != root) {
                    flag = false;
                    break;
                }
            }
        }
        if (flag) printf("Possible\n");
        else printf("Impossible\n");
        return 0;
    }


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