题目连接 : 传送阵
———————————————-.
Colored Sticks
Time Limit: 5000MS Memory Limit: 128000K
Total Submissions: 35437 Accepted: 9287
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
————————————–.
题目大意 就是有多个木棍 两头有颜色 对于不同的木棍 相同颜色的一段能连接到一块 问你所有的棍能不能接成一根棍子
解题思路:
应该想到如果颜色是用数字表示的就非常好解决了 只要判断一下这些每个颜色的度就能解决 注意!! 生成的图可能是个森林 所以要用并查集判断下 是否生成的是一个树(应该是环)
现在想的问题就只剩下字符串怎么转化成数字了 用map转化的话不可行 所以想到用tire树来解决 这样才不会爆内存
对于学会tire树的你相信不是个问题 注意的是 把每个串插入到树中的时候只要把最后一个字符所在的节点+1 就行了 再在tire中加上一个index(索引)的元素 记录这个串的编号 (查询操作是没用的)
刚学字符串10days 纯属个人解法 如有错误 请一定要指正
附本题代码
———————————————.
#include <bits/stdc++.h>
using namespace std;
#define LL long long int
#define lalal puts("********");
const int N = 1010101;
const int Max = 26;
char s1[11],s2[11];
int pre[505050];
int degree[505050];
typedef struct node
{
struct node *next[Max];
int num;
int index;
} Node;
//创建一个新节点
Node *createNew()
{
Node *p=new Node;
for(int i=0; i<Max; i++)
p->next[i]=NULL;
p->num=0;
return p;
}
Node *head;
int ind=0;
//插入一个字符串
Node *Insert_str(char str[])
{
int len=strlen(str);
// printf("len = %d-- ",len);
Node *t,*p=head;
for(int i=0; i<len; i++)
{
int c=str[i]-'a';
if( p->next[c] == NULL )
{
//lalal
t=createNew();
p->next[c]=t;
}
p=p->next[c];
//统计的时候要分清时机
// cout<<p->num<<"-"<<str[i]<<" ";
}
p->num++;
if(p->num==1) p->index=++ind;
return p;
}
int findi(int x)
{
int r=x;
while(r!=pre[r])
r=pre[r];
int i=x,j;
while(i!=j)
{
j=pre[i];
pre[i]=r;
i=j;
}
return r;
}
void join(int x,int y)
{
int fx=findi(x),fy=findi(y);
if(fx!=fy)
pre[fx]=fy;
}
void init()
{
for(int i=0; i<=500050; i++)
{
pre[i]=i;
degree[i]=0;
}
return ;
}
int main()
{
head = createNew();
init();
int num=0;
Node * tem1,*tem2 ;
while(~scanf("%s %s",s1,s2))
{
tem1 = Insert_str(s1);
tem2 = Insert_str(s1);
degree[tem1->index]++;
degree[tem2->index]++;
join(tem1->index,tem2->index);
}
for(int i=1; i<=ind; i++)
{
if(degree[i]%2 == 1) num++;
if(num>=3)
{
puts("Impossible");
break;
}
if(findi(1)!=findi(i))
{
puts("Impossible");
break;
}
}
if(num!=1) puts("Possible");
else puts("Impossible");
return 0;
}