zoukankan      html  css  js  c++  java
  • POJ 2513 【字典树】【欧拉回路】

    题意:

    有很多棒子,两端有颜色,告诉你两端的颜色,让你把这些棒子拼接起来要求相邻的接点的两个颜色是一样的。

    问能否拼接成功。

    思路:

    将颜色看作节点,将棒子看作边,寻找欧拉通路。

    保证图的连通性的时候用到并查集。

    这里颜色由于是字符串代替,所以需要用到字典树优化离散化过程。

    字典树的学习感谢博客http://www.ahathinking.com/archives/14.html

    重点是这个图很棒:

    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #include<map>
    #include<string>
    #include<iostream>
    #include<stdlib.h>
    using namespace std;
    int me[250000*2+55];
    int out[500005];
    struct ti
    {
        void add(char *,int);
        int findi(char *);
        ti *mine[26];
        int num;
    };
    void ti::add(char *s,int tmp)
    {
        int len=strlen(s);
        ti *next=this;
        for(int i=0;i<len;i++)
        {
            if(next->mine[s[i]-96]==NULL)
            {
                next->mine[s[i]-96]=(ti*)malloc(sizeof(ti));
                memset(next->mine[s[i]-96]->mine,NULL,sizeof(mine));
                next->mine[s[i]-96]->num=0;
            }
            next=next->mine[s[i]-96];
        }
        next->num=tmp;
    }
    int ti::findi(char *s)
    {
        int len=strlen(s);
        ti *next=this;
        for(int i=0;i<len;i++)
        {
            if(next->mine[s[i]-96]==NULL)
            {
                return 0;
            }
            next=next->mine[s[i]-96];
        }
        return next->num;
    }
    ti tree;
    int findme(int n)
    {
        if(n!=me[n])
            return me[n]=findme(me[n]);
        return n;
    }
    int main()
    {
        memset(tree.mine,NULL,sizeof(tree.mine));
        tree.num=0;
        char col1[15],col2[15];
        for(int i=1;i<=500050;i++)
        {
            me[i]=i;
        }
        int num=0;
        while(scanf("%s%s",col1,col2)!=EOF)
        {
            if(tree.findi(col1)==0)
            {
                num++;
                tree.add(col1,num);
            }
            if(tree.findi(col2)==0)
            {
                num++;
                tree.add(col2,num);
            }
            int tmpa=findme(tree.findi(col1));
            int tmpb=findme(tree.findi(col2));
            if(tmpa!=tmpb)
                me[tmpb]=tmpa;
            out[tree.findi(col1)]++;
            out[tree.findi(col2)]++;
        }
        int c=0;
        int x,y,z;
        x=y=z=0;
        for(int i=1;i<=num;i++)
        {
            if(me[i]==i)
                c++;
            if(out[i]&1)
                x++;
        }
        if(x==1||c>1||x>2)
            printf("Impossible
    ");
        else
            printf("Possible
    ");
    }
  • 相关阅读:
    代码重构(转)
    Apache负载均衡 配置
    恒久的忍耐
    setInterval全面的介绍
    引用 110个Oracle 常用函数的总结
    ssl和tls
    JSTL
    java异常处理的陋习(转载)
    Java 6 JVM参数选项大全(中文版)
    liunx基础常用命令
  • 原文地址:https://www.cnblogs.com/tun117/p/4859193.html
Copyright © 2011-2022 走看看