• poj-2513(字典树+欧拉通路)


    题意:给你n个火柴棍,每个火柴棍头和尾两种颜色,问你是否存在能够把这些火柴棍摆成一行的情况,两个相连的火柴棍的颜色需要一样;

    解题思路:最初的思路是用map标记颜色,然后把每种颜色看作点,每根火柴棍看作边,求欧拉路径,然后超时了。。。看了别人的写法,想起来了自己还学过字典树来着。。。然后用字典树找就行了,快很多

    代码:

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int maxn=500050;
    struct tnode
    {
        int pos;
        bool exsit;
        tnode *next[30];
        tnode()
        {
            for(int i=0;i<26;i++)
                next[i]=NULL;
            pos=0;exsit=false;
        }
    };
    tnode *root;
    int x,y;
    int flag;
    int dfn;
    int degree[maxn];
    int f[maxn];
    char s[15],t[15];
    tnode* newnode()
    {
        tnode *p=new tnode;
        for(int i=0;i<26;i++)
            p->next[i]=NULL;
        p->pos=0;p->exsit=false;
        return p;
    }
    void build_trie(char *s)
    {
        tnode *p=root;
        int slen=strlen(s);
        for(int i=0;i<slen;i++)
        {
            int id=s[i]-'a';
            if(p->next[id]==NULL)
            {
                p->next[id]=newnode();
            }
            p=p->next[id];
        }
        p->exsit=true;
        p->pos=++dfn;
    }
    int query(char *s)
    {
        tnode *p=root;
        int slen=strlen(s);
        for(int i=0;i<slen;i++)
        {
            int id=s[i]-'a';
            p=p->next[id];
            if(p==NULL)
                return 0;
        }
        if(p->exsit)
            return p->pos;
    }
    int build(char *str)
    {
        int zz=query(str);
        if(zz!=0)
            return zz;
        else
        {
            build_trie(str);
            return dfn;
        }
    }
    int findf(int u)
    {
        if(u==f[u])
            return u;
        else
        {
            f[u]=findf(f[u]);
            return f[u];
        }
    }
    void join(int x,int y)
    {
        int t1=findf(x);
        int t2=findf(y);
        if(t1!=t2)
            f[t2]=t1;
    }
    int main()
    {
        root=newnode();
        for(int i=1;i<=maxn;i++)
            f[i]=i;
        while(scanf("%s %s",s,t)!=EOF)
        {
            int x=build(s);
            int y=build(t);
            degree[x]++;degree[y]++;
            join(x,y);
        }
      //  cout<<dfn<<endl;
        int cnt=0;
        int fa=findf(1);
        for(int i=2;i<=dfn;i++)
            if(findf(i)!=fa)
                flag=1;
        if(flag)
        {
            printf("Impossible
    ");return 0;
        }
        for(int i=1;i<=dfn;i++)
        {
            if(degree[i]!=0)
            {
                if((degree[i]&1)==1)
                    cnt++;
            }
        }
      //  cout<<cnt<<endl;
        if(cnt==1||cnt>=3)
            flag=1;
         if(flag)
        {
            printf("Impossible
    ");
        }
        else
            printf("Possible
    ");
    }
    

      

  • 相关阅读:
    作业2 对称密钥密码系统安全性分析(B班同学评论)
    作业1 你如何看待信息安全问题影响(B班同学评论)
    作业1 你如何看待信息安全问题影响(A班同学评论)
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
    jQuery火箭图标返回顶部代码
  • 原文地址:https://www.cnblogs.com/huangdao/p/9638284.html
Copyright © 2020-2023  润新知