zoukankan      html  css  js  c++  java
  • POJ 2513 Colored Sticks

    思路:把每根筷子的两个端点的字符串看成一个点,建图,问题即转化为判断图是否是含有欧拉通路,满足两个条件:

    (1)图是连通图,(2)奇数度的点个数要么是0,要么是2。

    无向图判断是否连通很简单,并查集直接搞就行,最后看是不是只有一个连通分量。

    建图时把每个字符串转化为一个整数,这样才好建图,第一反应是用map,交了一发TLE,然后干脆直接用trie树吧,1000+ms过的,有点慢。

    #include<cstdio>
    #include<string>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    const int MAXN = 250010;
    typedef struct Node{
        int cnt;
        Node *child[26];
        Node(){
            cnt = 0;
            for(int i = 0;i < 26;i ++)
                child[i] = NULL;
        }
    }Node;
    Node* root;
    int father[(MAXN << 1)+10],ind[(MAXN << 1)+10],n;
    inline int update(char* str){
        Node *tmp = root;
        while(*str != ''){
            if(tmp->child[*str-'a'] == NULL){
                Node *p = new Node();
                tmp->child[*str-'a'] = p;
            }
            tmp = tmp->child[*str-'a'];
            str++;
        }
        if(tmp->cnt == 0) tmp->cnt = ++n;
        return tmp->cnt;
    }
    inline void init(){
        n = 0,root = new Node();
        memset(ind,0,sizeof ind);
        for(int i = 1;i <= MAXN*2;i ++)
            father[i] = i;
    }
    int find(int x){
        return x == father[x] ? x : father[x] = find(father[x]);
    }
    inline void merge(int x,int y){
        x = find(x);
        y = find(y);
        father[y] = x;
    }
    int main(){
        init();
        int x,y;
        char str1[20],str2[20];
    #ifndef ONLINE_JUDGE
        freopen("in.cpp","r",stdin);
    #endif
        while(~scanf("%s%s",str1,str2)){
            x = update(str1),y = update(str2);
            if(find(x) != find(y)) merge(x,y);
            ind[x]++,ind[y]++;
        }
        int sum = 0;
        for(int i = 1;i <= n;i ++){
            if(i == find(i)) sum ++;
            if(sum > 1){
                printf("Impossible
    ");
                return 0;
            }
        }
        sum = 0;
        for(int i = 1;i <= n;i ++){
            if(ind[i]&1) sum ++;
            if(sum > 2){
                printf("Impossible
    ");
                return 0;
            }
        }
        printf("Possible
    ");
        return 0;
    }


  • 相关阅读:
    VS2010安装笔记
    Blend4中文版中截取图片的方法
    改变窗口的位置 (转载)
    窗口的位置
    windows消息大全
    WM_MOUSELEAVE和WM_MOUSEHOVER使用
    setwindowpos
    无注册表的COM调用
    WM_CLOSE WM_QUIT WM_DESTROY 三者的区别
    WM_MOUSEWHEEL消息
  • 原文地址:https://www.cnblogs.com/anhuizhiye/p/3933145.html
Copyright © 2011-2022 走看看