您的位置:首页 > 其它

poj 2513 Colored Sticks (字典树 + 并查集)

2017-03-27 23:24 337 查看
题目链接:http://poj.org/problem?id=2513

Colored Sticks

Time Limit: 5000MS Memory Limit: 128000K
Total Submissions: 37025 Accepted: 9721
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

The UofA Local 2000.10.14
[Submit]   [Go Back]   [Status]  
[Discuss]


Home Page   

Go
Back  

To top

题意:有一些木棒,两头有对应的颜色,把这些木棒头上相同的颜色拼接起来,问是否能够连成一条直线

解析:这个可以换成图,就是判断是否是欧拉图,由于数据比较多,用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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: