POJ 2513 Colored Sticks
欧拉回路判定,并查集,trie树
Time Limit: 5000MS | Memory Limit: 128000K | |
Total Submissions: 31621 | Accepted: 8370 |
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
题意:给若干根两端涂上不同颜色的筷子,相同颜色的筷子端点可接在一起,问是否能将筷子接成一条直线
思路:将每种颜色看成结点,筷子看成边,建无向图,判断无向图是否是存在欧拉路径的连通图
判断欧拉图:用并查集判断图是否连通,判断是否存在欧拉回路,不存在奇点
判断存在欧拉路径:存在0或两个奇点
难点:题目卡了map和hash。。对字符串的转化只能用trie树了。。。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstdlib> #include<cstring> #include<algorithm> #include<map> #include<vector> using namespace std; const int maxn=510010; int cnt=0; int indeg[maxn]; int fa[maxn]; struct Node { int id; Node *next[26]; };Node root; int insert(char*s) //返回结点的id { Node *p=&root; for(int i=0;i<strlen(s);i++){ if(p->next[s[i]-'a']==NULL){ Node *newnode=(Node*)malloc(sizeof(Node)); memset(newnode,0,sizeof(Node)); p->next[s[i]-'a']=newnode; } p=p->next[s[i]-'a']; } if(p->id) return p->id; //如果结点已存在,直接返回 return p->id=++cnt; //不存在则返回新结点 } int find(int x) { return fa[x]==x?x:fa[x]=find(fa[x]); } int main() { char s1[20],s2[20]; memset(indeg,0,sizeof(indeg)); for(int i=0;i<maxn;i++) fa[i]=i; char s[40]; while(gets(s)&&strlen(s)){ sscanf(s,"%s%s",s1,s2); int u=insert(s1),v=insert(s2); indeg[u]++;indeg[v]++; //记录入度 int x=find(u),y=find(v); if(x!=y) fa[x]=y; //记录合并连通分量 } int n=0; bool flag=1; for(int i=1;i<=cnt;i++){ if(indeg[i]&1) n++; if(n>2){ //判断奇点数目 flag=0;break; } if(find(i)!=find(1)){ //判断连通性 flag=0;break; } } if(flag) cout<<"Possible"<<endl; else cout<<"Impossible"<<endl; return 0; }