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]
题意:
给定一捆木棍。每根木棍的每个端点涂有某种颜色。问:是否能将这些棍子首尾相连,排成
一条直线,且相邻两根棍子的连接处端点的颜色一样。
输入描述:
输入文件中包含若干行,每行为两个单词,用空格隔开,表示一根棍子两个端点的颜色。表
示颜色的单词由小写字母组成,长度不超过 10 个字符。木棍的数目不超过 250000。
输出描述:
如果木棍能按照题目的要求排成一条直线,输出"Possible",否则输出"Impossible"。
开始用map hash居然超时了。。。木棍看成边,颜色看成节点,则问题转化为是否存在欧拉路。
代码如下:
/*************************************************************************
> File Name: t.cpp
> Author: acvcla
> Mail: acvcla@gmail.com
> Created Time: 2014年10月21日 星期二 21时33分55秒
************************************************************************/
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<vector>
#include<cstring>
#include<map>
#include<queue>
#include<stack>
#include<string>
#include<cstdlib>
#include<ctime>
#include<set>
#include<math.h>
using namespace std;
typedef long long LL;
const int maxn = 500000 + 10;
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define pb push_back
int p[maxn],d[maxn];///d is the in_degree - out_degree
int ch[maxn*10][26];
int val[maxn*260];
struct Trie
{
int cnt,sz;
Trie(){
memset(ch[0],0,sizeof ch[0]);
memset(val,0,sizeof(val[0])*100);
cnt=1;
sz=0;
}
void init(){
Trie();
}
int idx(char c){return c-'a';}
int push(string &s){
int n=s.size();
int u=0,add=0;
for(int i=0;i<n;i++){
int x=idx(s[i]);
if(!ch[u][x]){
memset(ch[cnt],0,sizeof ch[cnt]);
ch[u][x]=cnt++;
add=1;
}
u=ch[u][x];
}
if(add)val[u]=sz++;
return val[u];
}
}A;
int cnt=0;
int findx(int x){
return p[x]==x?x:p[x]=findx(p[x]);
}
void init(){
for(int i=0;i<=500000;i++)p[i]=i;
memset(d,0,sizeof d);
A.init();
}
void Union(int u,int v){
p[findx(u)]=findx(v);
}
void AddEdge(string a,string b){
int u=A.push(a),v=A.push(b);
//printf("%d %d\n",u,v);
d[u]++;
d[v]++;
Union(u,v);
}
int main(){
char a[20],b[20];
init();
bool ok=true;
while(~scanf("%s%s",a,b)){
if(ok)AddEdge(a,b);
if(A.sz>250015){
ok=false;
}
}
int even=0;
int cnt=A.sz;
if(ok)for(int i=0;i<cnt;i++){
//cout<<i<<' '<<d[i]<<endl;
if(d[i]&1){
even++;
if(even>2){
ok=false;break;
}
}
}
int x=findx(0);
if(even==1){ok=false;}
if(ok)for(int i=1;i<cnt;i++)if(x!=findx(i)){
ok=false;break;
}
puts(ok?"Possible":"Impossible");
return 0;
}