zoukankan      html  css  js  c++  java
  • poj2513——判断是否为存在欧拉路径的连通图(并查集,trie树)

    POJ 2513    Colored Sticks

    欧拉回路判定,并查集,trie树

    Time Limit: 5000MS   Memory Limit: 128000K
    Total Submissions: 31621   Accepted: 8370

    Description

    You are given a bunch of wooden sticks. Each endpoint of each stick is colored with some color. Is it possible to align the sticks in a straight line such that the colors of the endpoints that touch are of the same color?

    Input

    Input is a sequence of lines, each line contains two words, separated by spaces, giving the colors of the endpoints of one stick. A word is a sequence of lowercase letters no longer than 10 characters. There is no more than 250000 sticks.

    Output

    If the sticks can be aligned in the desired way, output a single line saying Possible, otherwise output Impossible.

    Sample Input

    blue red
    red violet
    cyan blue
    blue magenta
    magenta cyan
    

    Sample Output

    Possible


    题意:给若干根两端涂上不同颜色的筷子,相同颜色的筷子端点可接在一起,问是否能将筷子接成一条直线
    思路:将每种颜色看成结点,筷子看成边,建无向图,判断无向图是否是存在欧拉路径的连通图
    判断欧拉图:用并查集判断图是否连通,判断是否存在欧拉回路,不存在奇点
    判断存在欧拉路径:存在0或两个奇点

    难点:题目卡了map和hash。。对字符串的转化只能用trie树了。。。
    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<map>
    #include<vector>
    
    using namespace std;
    
    const int maxn=510010;
    
    int cnt=0;
    int indeg[maxn];
    int fa[maxn];
    
    struct Node
    {
        int id;
        Node *next[26];
    };Node root;
    
    int insert(char*s)   //返回结点的id
    {
        Node *p=&root;
        for(int i=0;i<strlen(s);i++){
            if(p->next[s[i]-'a']==NULL){
                Node *newnode=(Node*)malloc(sizeof(Node));
                memset(newnode,0,sizeof(Node));
                p->next[s[i]-'a']=newnode;
            }
            p=p->next[s[i]-'a'];
        }
        if(p->id) return p->id;  //如果结点已存在,直接返回
        return p->id=++cnt;   //不存在则返回新结点
    }
    
    int find(int x)
    {
        return fa[x]==x?x:fa[x]=find(fa[x]); 
    }
    
    int main()
    {
        char s1[20],s2[20];
        memset(indeg,0,sizeof(indeg));
        for(int i=0;i<maxn;i++) fa[i]=i;
        char s[40];
        while(gets(s)&&strlen(s)){
            sscanf(s,"%s%s",s1,s2);
            int u=insert(s1),v=insert(s2);
            indeg[u]++;indeg[v]++;    //记录入度
            int x=find(u),y=find(v);    
            if(x!=y) fa[x]=y;     //记录合并连通分量
        }
        int n=0;
        bool flag=1;
        for(int i=1;i<=cnt;i++){
            if(indeg[i]&1) n++;
            if(n>2){      //判断奇点数目
                flag=0;break;
            }
            if(find(i)!=find(1)){  //判断连通性
                flag=0;break;
            }
        }
        if(flag) cout<<"Possible"<<endl;
        else cout<<"Impossible"<<endl;
        return 0;
    }
    poj2513
    没有AC不了的题,只有不努力的ACMER!
  • 相关阅读:
    118.Java_前定义
    117.数据结构概述(定义,基本术语,层次)
    116.C语言_文件
    115.C语言_函数
    java数组
    sql语句学习(第二季
    linux查看内存
    增强型for和Iterator学习
    ArrayList和LinkedList
    java并发回答
  • 原文地址:https://www.cnblogs.com/--560/p/4330867.html
Copyright © 2011-2022 走看看