zoukankan      html  css  js  c++  java
  • [POJ]POJ1328(trie)

    题意:有一些木棍,每根木棍两端各有一种颜色,两个有相同颜色的端可以连在一起,问这些木棍能不能连成一条线。

    把颜色看作点,木棍看作边,转化为求图中有没有欧拉路,无向图有欧拉路等价于无向图联通且奇度点为两个或零个,证明略。

    判断联通用并查集,点的度直接统计即可。

    问题在于把字符串映射成int,stlmap太慢,用trie实现。

    (因为有零根木棍的情况WA了一下午...)

    #include <cstdio>
    #include<map>
    #include<iostream>
    #include<string>
    #include<cstring>
    
    using namespace std;
    
    typedef long long int LL;
    
    #define st first
    #define nd second
    #define pb push_back
    #define mp make_pair
    #define pll pair <LL, LL>
    #define pii pair <int, int>
    #define rep(i,x) for(int i=1;i<=x;i++)
    
    const int N = 5e5+7;
    const int MX = 1e9+7;
    const LL INF = 1e18+9LL;
    const int mod = 20071027;
    
    int n,odd,cnt;
    
    int fa[N],deg[N],sz[N];
    
    struct Trie{
        int val[600010],ch[600010][26];
        int sz;
        void init(){
            memset(ch[0],0,sizeof(ch[0]));
            sz=1;
        }
        int index(char c){return c-'a';}
        void insert(char* a,int v){
            int u=0,l=strlen(a);
            for(int i=0;i<l;i++){
                int x=index(a[i]);
                if(!ch[u][x]){
                    memset(ch[sz],0,sizeof(ch[sz]));
                    val[sz]=0;
                    ch[u][x]=sz++;
                }
                u=ch[u][x]; 
            }
            val[u]=v;
        }
        int find(char* a){
            int u=0,l=strlen(a);
            for(int i=0;i<l;i++){
                int x=index(a[i]);
                if(!ch[u][x])return 0;
                u=ch[u][x];
            }
            return val[u];
        }
    }trie;
    
    
    int find(int x){
        if(fa[x]==x)return x;
        return fa[x]=find(fa[x]);
    }
    
    void merge(int x,int y){
        deg[x]++;
        deg[y]++;
        int fx=find(x);
        int fy=find(y);
        fa[fx]=fy;
        if(fx!=fy)sz[fy]+=sz[fx];
    }
    
    int main(){
        char a[12],b[12];
        rep(i,N-1)fa[i]=i,sz[i]=1;
        trie.init();
        while(scanf("%s%s",a,b)==2){
            if(!trie.find(a))trie.insert(a,++cnt);
            if(!trie.find(b))trie.insert(b,++cnt);
            merge(trie.find(a),trie.find(b));
        }
        rep(i,cnt)if(deg[i]%2)odd++;
        if(sz[find(1)]>=cnt&&(odd==2||odd==0))printf("Possible
    ");
        else printf("Impossible
    "); 
    }
  • 相关阅读:
    python thrift
    redis 知识点
    Spring其他注解和xml配置(不常用的)
    Spring常用的的注解以及对应xml配置详解
    Eureka的工作原理简介
    SpringBoot的自动配置实现和介绍
    SpringBoot多配置文件,切换环境
    数据卷介绍和常用的服务部署
    Spring Security简介
    在Java中入门,读取和创建Excel,Apache POI的使用
  • 原文地址:https://www.cnblogs.com/xutianshu/p/10462078.html
Copyright © 2011-2022 走看看