码迷,mamicode.com
首页 > 其他好文 > 详细

poj2513——判断是否为欧拉图(并查集,trie树)

时间:2015-03-11 21:19:21      阅读:151      评论:0      收藏:0      [点我收藏+]

标签:

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


题意:给若干根两端涂上不同颜色的筷子,相同颜色的筷子端点可接在一起,问是否能将筷子接成一条直线
思路:将每种颜色看成结点,筷子看成边,建无向图,判断无向图是否存在欧拉回路。判断欧拉回路:用并查集判断图是否连通,判断是否存在超过两个奇点(入度为奇数的点)
难点:题目卡了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

 

poj2513——判断是否为欧拉图(并查集,trie树)

标签:

原文地址:http://www.cnblogs.com/--560/p/4330867.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!