http://poj.org/problem?id=2513
和离散数学有关 欧拉回路问题
同一颜色的标记为同一点 同一stick 的两端为相连状态
数学什么的 最不擅长了 看了别人的解析
两个限制条件
1 图为联通 可用并查集判断
2 度 (出度+入度)数为基数的点为0 或者为 2 输入时相加
不满足上述两个条件中的任何一个 都Impossible
存颜色和查询要用字典树 用map超时
代码及其注释:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<map>
#include<queue>
#include<cmath>
#define LL long long
using namespace std;
const int N=550100;
int f[N];//并查集
int num[N];//度(出度+入度)
int I;//总节点数 全局变化
struct node
{
struct node *next[26];
int k;
}*head;
inline int findx(int x)
{
if(f[x]!=x)
f[x]=findx(f[x]);
return f[x];
}
int insert(char s[])//插入颜色 并返回颜色的对应数字
{
struct node *t,*w;
int n=strlen(s);
t=head;
for(int i=0;i<n;++i)
{
if(t->next[s[i]-'a']==NULL)
{
w=new node;
for(int j=0;j<26;++j)
w->next[j]=NULL;
w->k=-1;
t->next[s[i]-'a']=w;
}
t=t->next[s[i]-'a'];
}
if(t->k==-1)
t->k=I++;
return t->k;
}
int main()
{
//freopen("data.txt","r",stdin);
for(int i=0;i<N;++i)
{
f[i]=i;
num[i]=0;
}
head=new node;
for(int i=0;i<26;++i)
head->next[i]=NULL;
head->k=-1;
char stemp1[12],stemp2[12];
I=0;
int k1,k2;
while(scanf("%s %s",stemp1,stemp2)!=EOF)
{
k1=insert(stemp1);
k2=insert(stemp2);
int l1=findx(k1);
int l2=findx(k2);
if(l1!=l2)//并查集 合并
f[l1]=k2;
++num[k1];//增加度
++num[k2];
}
int l;
int k=findx(0);
int sum=0;
for(l=0;l<I;++l)
{
if(findx(l)!=k)//图不联通
{
printf("Impossible\n");
return 0;
}
if(num[l]%2)
++sum;
}
if(sum==0||sum==2)//只有基数度的点为0 和 为2 时可以
printf("Possible\n");
else
printf("Impossible\n");
return 0;
}