这道题涉及的知识点比较多
前面的博客是为这道题打基础
步入正题,题意是说给出一堆木棒,每根木棒的左边和右边颜色不一样,求能否将所有的木棒按规则连成一条直线,规则是相连的木棒端点处颜色必须一致。
如果可以输出Possible
例如题目中给出的例子(后面的序号是我自己加的)
blue red 1 red violet 2 cyan blue 3 blue magenta 4 magenta cyan 5
可以按照 4 5 3 1 2的顺序连接起来。
解题思路就是利用并查集,字典树,以及欧拉回路的知识点,
如果不知道并查集可以参照本博客的并查集那篇博客,然后做畅通工程 HDU - 1232这道题练习一下,本博客上也有解题思路,然后了解一下字典树,可以参考一下http://blog.csdn.net/jiutianhe/article/details/8076835这篇文章,讲的很清楚了,欧拉回路简单了解一下,可以参考这篇博客相关内容的讲解。http://blog.csdn.net/lyy289065406/article/details/6647445。
然后贴上我的代码
#include<cstdio>
#include<iostream>
#include<cstring>
#define N 2500005*2
using namespace std;
int pre[N];
int indgr[N];
int trie[N][26];
int nodeNum, pr, cnt, oddDgr, root;
int find(int x)
{
int r=x;
while(r!=pre[r])//若r的前导点不是它本身
{
r=pre[r];//查找
}
//路径压缩
int i=x,j;
while(i!=r)
{
j=pre[i];
pre[i]=r;
i=j;
}
return r;//返回查找到的根节点
}
//合并
void join(int x,int y)
{
int rx=find(x),ry=find(y);
if(rx!=ry)
{
pre[rx]=ry;
}
}
int main()
{
char color[15];
int i;
for(i=0; i<N; ++i)
pre[i]=i;
while(~scanf("%s",color))
{
cnt++;
int cur=0,L=strlen(color);
for(i=0; i<L; ++i)
{
int k=color[i]-'a';
if(!trie[cur][k])
trie[cur][k]=++nodeNum;
cur=trie[cur][k];
}
++indgr[cur];
if(cnt%2)pr=cur;
else
join(pr,cur);
}
for( i=0; i<=nodeNum; ++i)
{
if(indgr[i]%2)++oddDgr;
if(indgr[i]&&pre[i]==i) ++root;
if(oddDgr>2||root>1) break;
}
if(((oddDgr==0 || oddDgr==2) && root==1) || (oddDgr==0 && root==0))
printf("Possible\n");
else
printf("Impossible\n");
return 0;
}