题目链接:http://poj.org/problem?id=2513
Colored Sticks
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 |
[Submit] [Go Back] [Status] [Discuss]
题意:有一些木棒,两头有对应的颜色,把这些木棒头上相同的颜色拼接起来,问是否能够连成一条直线
解析:这个可以换成图,就是判断是否是欧拉图,由于数据比较多,用map会超时,所以就用字典树记录编号,用并查集判断是否是欧拉图,还有就是记录每个节点入度出度,然后就是看度数和为奇数的节点为0个或者2个,
代码:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#define N 250009
using namespace std;
const int INF = 0x3f3f3f3f;
int pre[N<<1], edge[N<<1], cnt, n;
char s1[12], s2[12];
typedef struct node
{
struct node *nx[33];
int num;
node()
{
num = 0;
memset(nx, 0, sizeof(nx));
}
}Q, *T;
T root = new node();
void init()
{
memset(edge, 0, sizeof(edge));
cnt = n = 0;
for(int i = 0; i < N; i++)
pre[i] = i;
}
int Find(char *s)
{
T p = root;
for(int i = 0; s[i]; i++)
{
int id = s[i] - 'a';
if(p->nx[id] == NULL) return -1;
p = p->nx[id];
}
return p->num;
}
void Creat(char *s, int &x)
{
T p = root;
for(int i = 0; s[i]; i++)
{
int id = s[i] - 'a';
if(p->nx[id] == NULL) p->nx[id] = new node();
p = p->nx[id];
}
x = p->num = ++cnt;
}
int get_pre(int x)
{
return x == pre[x] ? x : (pre[x] = get_pre(pre[x]));
}
void Union(int x, int y)
{
int fx = get_pre(x);
int fy = get_pre(y);
if(fx != fy) pre[fx] = fy;
}
bool check()
{
int num = 0;
for(int i = 1; i <= n; i++)
if(edge[i]&1) num++;
if(num != 0 && num != 2) return false;
int s = get_pre(1);
for(int i = 2; i <= n; i++)
{
if(s != get_pre(i)) return false;
}
return true;
}
int main()
{
init();
while(~scanf("%s %s", s1, s2))
{
int x = Find(s1);
int y = Find(s2);
if(x == -1) Creat(s1, x);
if(y == -1) Creat(s2, y);
edge[x]++; edge[y]++;
n = max(n, max(x, y));
Union(x, y);
}
if(check()) printf("Possible\n");
else puts("Impossible");
return 0;
}