POJ-2513 Colored Sticks

题目大意:

给定一捆木棍,每根木棍的每个端点涂有某种颜色。问你是否能将这些棍子首尾相连,排成一条直线,且相邻两根棍子的连接处端点的颜色一样

解题思路:

应该可以说是判断欧拉路径的裸题了

不过有些地方很蛋疼= =我一开始写的是vector+string+map用了三个STL模板写的,结果TLE

所以这道题我比较推荐用Trie(字典树) + 并查集来处理,相对来说比较稳

以及玛德这道题为什么有菊苣能写到16ms并且内存也只用了652K快哭了

代码:

#include <cstdio>
#include <cstring>
using namespace std;

typedef struct node{
    int num;
    node *next[26];
}Trie;

const int maxn = 250000 * 2 + 10;

int tot, pre[maxn], deg[maxn];

Trie *init(Trie *rt){
    rt -> num = 0;
    for(int i = 0; i < 26; ++i) rt -> next[i] = NULL;
    return rt;
}
Trie *createTrie(Trie *rt, char *s){
    Trie *p = rt;
    int v, len = strlen(s);
    for(int i = 0; i < len; ++i){
        v = s[i] - 'a';
        if(p -> next[v] == NULL){
            p -> next[v] = new Trie;
            p = p -> next[v];
            p = init(p);
            p -> num = 0;
        }else p = p -> next[v];
    }
    p -> num = tot++;
    return rt;
}
int getNum(Trie *rt, char *s){
    Trie *p = rt;
    int v, len = strlen(s);
    for(int i = 0; i < len; ++i){
        v = s[i] - 'a';
        if(p -> next[v] == NULL) return 0;
        else p = p -> next[v];
    }
    return p -> num;
}
void clearTrie(Trie *t){
    if(t == NULL) return;
    for(int i = 0; i < 26; ++i){
        clearTrie(t -> next[i]);
    }
    delete t;
}
int findfather(int x){
    return pre[x] = (pre[x] == x ? x : findfather(pre[x]));
}
int judge(){
    int tmp = findfather(1);
    for(int i = 2; i < tot; ++i){
        if(findfather(i) != tmp) return 0;
    }
    return 1;
}
int main(){
    tot = 1;
    int a, b;
    Trie *t; t = new Trie; t = init(t);
    char color1[12] = {0}, color2[12] = {0};
    for(int i = 0; i < maxn; ++i) pre[i] = i, deg[i] = 0;
    while(~scanf(" %s %s", color1, color2)){
        if(getNum(t, color1) == 0) t = createTrie(t, color1);
        if(getNum(t, color2) == 0) t = createTrie(t, color2);
        a = getNum(t, color1);
        b = getNum(t, color2);
        ++deg[a]; ++deg[b];
        pre[findfather(a)] = findfather(b);
    }
    int flag = 0;
    for(int i = 1; i < tot; ++i){
        flag += deg[i] & 1;
    }

    if(flag == 0 || flag == 2) flag = judge();
    else flag = 0;

    if(flag) puts("Possible");
    else puts("Impossible");
    clearTrie(t);
    return 0;
}


posted @ 2016-08-04 11:06  _Wilbert  阅读(175)  评论(0编辑  收藏  举报