Time Limit: 5000MS | Memory Limit: 128000K | |
Total Submissions: 27373 | Accepted: 7240 |
Description
Input
Output
Sample Input
blue red red violet cyan blue blue magenta magenta cyan
Sample Output
Possible
Hint
Source
给定一些木棒,木棒两端都涂上颜色,求是否能将木棒首尾相接,连成一条直线,要求不同木棒相接的一边必须是相同颜色的。
貌似就是判断欧拉回路。
由图论知识可以知道,无向图存在欧拉路的充要条件为:
① 图是连通的;
② 所有节点的度为偶数,或者有且只有两个度为奇数的节点。
图的连通可以利用并查集去判断。
度数的统计比较容易。
数据比较大,首先需要将颜色的字符串和数字一一对应起来。
虽然可以用map,但是map效率不高,肯定会超时的。
最好的办法的是建立字典树。
将字符串和数字一一对应起来。
注意本题的数据有没有木棒的情况,要输出Possible。
#include<iostream> #include<cstdio> #include<string> #include<cstring> using namespace std; const int MAX=250000+10; int par[MAX]; int dev[MAX]; int hash[MAX]; //定义字典树结构体 struct Trie { Trie* next[26]; int flag; Trie() { flag=-1; } }; //***************************************************************** Trie *root; int ind; //初始化root void init() { root=new Trie; memset(root,0,sizeof(Trie)); } //***************************************************************** //***************************************************************** //将str插入以root为根节点的字典树中 int insert(char *str) { int len = strlen(str); Trie *s = root; for (int i = 0; i < len; i++) { if (s->next[str[i] - 'a']) s = s->next[str[i] - 'a']; else { Trie* t = new Trie; memset(t, 0, sizeof (Trie)); s->next[str[i] - 'a'] = t; s = t; } } return s->flag = ind++; } //***************************************************************** //***************************************************************** //查找字典树中是否有元素str int find(char *str) { int len = strlen(str); Trie *s = root; for (int i = 0; i < len; i++) { if (s->next[str[i] - 'a']) s = s->next[str[i] - 'a']; else return -1; } return s->flag;/////////////////////flag可能不标志为单词结尾 } //***************************************************************** int Get_par(int a) //查找a的父亲节点并压缩路径 { if(par[a]==a) return par[a]; //注意语句的顺序 int pa=par[a]; par[a]=Get_par(par[a]); return par[a]; } void Merge(int a,int b) //合并a,b { int pa,pb; pa=Get_par(a); pb=Get_par(b); if(pa==pb) return; par[pa]=pb; } int main() { // string a,b; char s1[15],s2[15]; int i; int tag=0; init(); // map<char [20],int>Map; for(i=0;i<MAX;i++) { par[i]=i; dev[i]=0; hash[i]=0; } ind=0; // freopen("in.txt","r",stdin); while(~scanf("%s%s",s1,s2)) { int a=find(s1); int b=find(s2); // printf("s1=%s s2=%s\n",s1,s2); // cout<<"a="<<a<<" b="<<b<<endl; if(-1==a) a=insert(s1); if(-1==b) b=insert(s2); // cout<<"a="<<a<<" b="<<b<<endl; dev[a]++; dev[b]++; Merge(a,b); } int odddev=0; for(i=0;i<ind;i++) { // printf("par[%d]=%d\n",i,par[i]); if(par[i]==i)tag++; if(dev[i]%2)odddev++; if(tag>1||odddev>2) break; } if((tag==1||tag==0)&&(odddev==2||odddev==0)) printf("Possible\n"); else printf("Impossible\n"); /* if(tag>1||odddev>2) printf("Impossible\n"); else printf("Possible\n"); */ return 0; }