讲一个木棍看成一条无向边,然后两边的颜色看做节点,统计度数,然后根据无向图欧拉通路的性质判断即可。
注意图的联通性。
此题用map会超时,我用了trie,trie的数组大小还真是个学问。。。。。。。。
Colored Sticks
Time Limit: 5000MS | Memory Limit: 128000K | |
Total Submissions: 26948 | Accepted: 7136 |
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.
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<utility>
#include<vector>
#include<map>
using namespace std;
#define MAXK 1010100
#define MAXN 510100
#define MAX 27
int set[MAXN],deg[MAXN];
int p;
struct Trie
{
int sz,t[MAXK][MAX];
int jud[MAXK];
Trie()
{
sz=1;
memset(t[0],-1,sizeof(t));
jud[0]=0;
}
void clear()
{
sz=1;
memset(t[0],-1,sizeof(t));
jud[0]=0;
}
int idx(char c)
{
return c-'a';
}
void insert(char* s,int v)
{
int u=0,n=strlen(s);
for(int i=0;i<n;i++)
{
int c=idx(s[i]);
if(t[u][c]==-1)
{
memset(t[sz],-1,sizeof(t[sz]));
jud[sz]=0;
t[u][c]=sz++;
}
u=t[u][c];
}
jud[u]=v;
}
int search(char* s)
{
int u=0,n=strlen(s);
for(int i=0;i<n;i++)
{
int c=idx(s[i]);
if(t[u][c]==-1) return -1;
u=t[u][c];
}
if(jud[u]) return jud[u];
return -1;
}
};
Trie t;
void init()
{
for(int i=0;i<MAXN;i++)
set[i]=i,deg[i]=0;
}
int find(int a)
{
int root=a;
int temp;
while(set[root]!=root)
root=set[root];
while(set[a]!=root)
{
temp=a;
a=set[a];
set[temp]=root;
}
return root;
}
bool merge(int a,int b)
{
int x=find(a);
int y=find(b);
if(x==y)
return false;
set[x]=y;
return true;
}
char s1[20],s2[20];
bool eluer()
{
int ort=-1;
int cnt=0;
for(int i=1;i<p;i++)
{
if(ort==-1) ort=i;
if(deg[i]%2==1 && cnt>2) return false;
if(deg[i]%2==1) cnt++;
}
for(int i=1;i<p;i++)
if(find(i)!=find(ort)) return false;
return true;
}
int main()
{
init();
t.clear();
p=1;
while(~scanf("%s%s",s1,s2))
{
if(t.search(s1)==-1)
t.insert(s1,p++);
int u=t.search(s1);
if(t.search(s2)==-1)
t.insert(s2,p++);
int v=t.search(s2);
deg[u]++,deg[v]++;
merge(u,v);
}
if(eluer())
printf("Possible\n");
else
printf("Impossible\n");
return 0;
}