poj 2513 连接火柴 字典树+欧拉通路 好题

Colored Sticks
Time Limit: 5000MS   Memory Limit: 128000K
Total Submissions: 27134   Accepted: 7186

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

Hint

Huge input,scanf is recommended.

Source

 
题意: 有很多个火彩 每头都有颜色   相同的颜色可以和另外的火柴相接  问这些火柴能不能连接成一条线 
 
思路:  很明显这是一个欧拉通路问题      一笔画画完整个通路 
用字典树标记字符串对应的id
用map超时
#include<stdio.h>
#include<string>
#include<string.h>
#include<map>
#include<malloc.h>
using namespace std;
#define N 250000+10
char s1[100],s2[100];
int rank[N],fa[N],num[N],co=0;
struct haha
{
    int id;
    struct haha *next[26];
}*root;
struct haha * creat()
{
    int i;
    struct haha *p;
    p=(struct haha *)malloc(sizeof(struct haha));
    p->id=-1;
    for(i=0;i<26;i++) p->next[i]=NULL;
    return p;
};
int update(char *s)
{
     int d,pos,i;
     struct haha *p;
     p=root;d=strlen(s);
     for(i=0;i<d;i++)
     {
         pos=s[i]-'a';
         if(p->next[pos]==NULL)
         {
             p->next[pos]=creat();
             p=p->next[pos];
         }
         else
         {
             p=p->next[pos];
         }
     }
     if(p->id==-1)
     p->id=co++;
     return p->id;
}
int  find(int n)
{
    return n==fa[n]?n:fa[n]=find(fa[n]);
}
void join(int a,int b)
{
        if(rank[a]>rank[b])
        {
            fa[b]=a;
            rank[a]+=rank[b];
        }
        else
        {
            fa[a]=b;
            rank[b]+=rank[a];
        }
}
int main()
{
    int i,j,k,cnt=0,a,b,rem;
    for(i=0;i<N;i++)
    {
        rank[i]=1;fa[i]=i;
    }
    memset(num,0,sizeof(num));
    root=creat();
    while(scanf("%s %s",s1,s2)!=EOF)
    {
         a=update(s1);
         b=update(s2);

         num[a]++;num[b]++;
         a=find(a);b=find(b);
         if(a==b) continue;
          join(a,b);
    }
    cnt=0;
    int temp=find(0);
    for(i=0;i<N;i++)
    {
        if(num[i]%2==1) cnt++;
        if(cnt>2) {printf("Impossible
");return 0;}
        if(num[i]!=0&&find(i)!=temp) {printf("Impossible
");return 0;}
    }
    printf("Possible
");
    return 0;
}

原文地址:https://www.cnblogs.com/dyllove98/p/3188514.html