您的位置:首页 > 其它

POJ 2513 Colored Sticks

2015-08-17 14:54 369 查看
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

/*

题目大意:

给定不超过250000根棍子,棍子上平分为分为两种颜色,问可不可以将所有的棍子(连接点颜色相同)连在一起,如果可以的话输出Possible否则Impossible.

解题思路:

将题目理解为给定一些无向边,将颜色理解为一个个的点,题目就转化为求这些无向边中是否存在一条欧拉路径,将所有的边全都经过而不重复。关键是将颜色转换为独立点,需要用到字典树(trie),刚刚看到这道题想用map,不过看到250000的数据就没敢...用map映射的话应该会超的,这时从POJ 2418上学习 到的经验!剩下的就好理解了,用字典树返回颜色编号,用并查集判断这个图是否为联通图,不是联通图不会有欧拉回路存在。最后通过每个点的度数判断是否为欧拉路或欧拉回路就ok了。记得数组至少开到500001,有边界数据(亲测),刚开始还以为250000根棍子最多有125000种颜色,开到126000足够了,结果RE。

*/

#include <iostream>
#include <algorithm>
#include <string>
#include <cstring>
#include <queue>
#include <stack>
#include <cmath>
#include <vector>
#include <cstdio>
#include <map>
#include <set>
const int INF = 0x3f3f3f3f;

using namespace std;
/*代码较挫,字典树虽说拿手但是我写的一般都点乱*/
struct node
{
int num;
node *next[26];
}*head,*p,*q;
int i,k = 1,flag,ant,ans[500001],vis[500001];

int g(int x)
{
while(x != vis[x])
x = vis[x];
return x;
}
void f(int x,int y)
{
int u = g(x);
int v = g(y);
if(u != v)
{
vis[u] = v;
}
}

node* getnew(node *l)
{
l = new node;
for(int i=0; i<26; i++)
l->next[i] = NULL;
l->num = -1;
return l;
}
void gettree(char stu[])
{
for(i = 0,p = head; stu[i]!='\0' ; i++)
{
if(stu[i+1] == '\0')
{
if(p->next[stu[i]-'a'] == NULL)
{
q = getnew(q);
q->num = k++;
p->next[stu[i]-'a'] = q;
if(flag == 1)
ant = q->num;
if(flag == 2)
{
f(ant,q->num);ans[ant]++;ans[q->num]++;
}
}
else
{
if(p->next[stu[i]-'a']->num == -1)
p->next[stu[i]-'a']->num = k++;
if(flag == 1)
ant = p->next[stu[i]-'a']->num;
if(flag == 2)
{
f(ant,p->next[stu[i]-'a']->num);ans[ant]++;ans[p->next[stu[i]-'a']->num]++;
}
}
}
else
{
if(p->next[stu[i]-'a'] == NULL)
{
q = getnew(q);
p->next[stu[i]-'a'] = q;
p = p->next[stu[i]-'a'];
}
else
p = p->next[stu[i]-'a'];
}
}
}

int main()
{
char stu[15],stv[15];
for(i=0;i<=500000;i++)
{
vis[i] = i;ans[i]= 0;
}
head = getnew(head);
while(~scanf("%s %s",stu,stv))
{
flag = 1;gettree(stu);flag = 2;gettree(stv);
}
bool Flag = false,F = false;
for(i = 1;i < k;i++)
{
if(vis[i] == i && !Flag)
{
Flag = true;
}
else if(vis[i] == i && Flag)
{
F = true;break;
}
}
if(F)
printf("Impossible\n");
else
{
int s = 0;
for(i = 1;i < k;i++)
{
if(ans[i]%2)
s++;
}
if((s == 2) || (s == 0))
printf("Possible\n");
else
printf("Impossible\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: