poj 2513 Colored Sticks
http://poj.org/problem?id=2513
题意:有一些棒子,每一根的两头都有两个颜色,将这些棒子相连并且被两根棒子接头处是相同的颜色,求一些这样的棒子是否都可以全部连起来;
思路:首先用tree树给每一种颜色编号,然后用并查集+欧拉路(只有两个或零个奇数结点);
代码:
View Code
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
using namespace std;
int f[500010] = {0};
int n = 0;
int nn[500010] ={0};
struct node
{
int num;
node *next[27];
};
node *head = NULL;
node *temp = NULL;
node * get()
{
temp = new node;
for(int i = 0;i < 27; ++i)
temp->next[i] = NULL;
temp->num = 0;
return temp;
}
void init()
{
head = get();
for(int i = 0;i < 500010; ++i)
{
f[i] = i;
nn[i] = 0;
}
n = 0;
}
char a[15] = {0};
char b[15] ={0};
int x = 0;
int y = 0;
int qq(char *s)
{
node *temp1 = head;
int q = 0;
for(int i = 0; s[i]; ++i)
{
q = s[i] - 'a';
if(temp1->next[q] == NULL)
temp1->next[q] = get();
temp1 = temp1->next[q];
}
if(temp1->num != 0)
return temp1->num;
else
{
++n;
temp1->num = n;
return n;
}
}
int find(int x)
{
if(x != f[x])
f[x] = find(f[x]);
return f[x];
}
void unio(int a,int b)
{
int x = find(a);
int y = find(b);
if(x != y)
f[x] = y;
}
bool check()
{
int num = 0;
int tt = find(1);
for(int i = 1;i <= n; ++i)
{
if(find(i) != tt)
return 0;
if(nn[i]%2)
++num;
}
if(num == 0 || num == 2)
return 1;
return 0;
}
int main()
{
//freopen("input.txt","r",stdin);
init();
while(scanf("%s%s",a,b) != EOF)
{
x = qq(a);
++nn[x];
y = qq(b);
++nn[y];
unio(x,y);
}
if(check())
printf("Possible\n");
else
printf("Impossible\n");
return 0;
}