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; }