现在的位置: 首页 > 综合 > 正文

PKU 2513 Colored Sticks – Trie树+并查集+欧拉通路

2012年08月01日 ⁄ 综合 ⁄ 共 1705字 ⁄ 字号 评论关闭

题目大意:

有n根棍子(n<250000),每根棍子两端都涂上颜色,颜色用长度小于10的字符串表示,问能否将所有的棍子排成一排,使得每两根棍子衔接的地方颜色相同.

分析:

题目很明确,将所有的颜色看做节点.连接两种颜色的棍子看做节点之间的连边.问是否存在一条欧拉通路.

字典树的目的是给每种颜色编号.用并查集来判断无向图是否连通.最后要做的就是统计每种颜色的出现次数了.

 

  1. /*
  2. PKU2513 Colored Sticks
  3. */
  4. #include <stdio.h>
  5. #include <string.h>
  6. #include <malloc.h>
  7. #define clr(a) memset(a,0,sizeof(a))
  8. #define CN 26
  9. #define MEM 6000005
  10. #define M 600005
  11. int d[MEM], nd;
  12. int f[M], nf;
  13. int FindSet(int f[],int i){
  14.     int j=i,t;
  15.     while(j!=f[j]) j=f[j];
  16.     while(i!=f[i]){ t=f[i]; f[i]=j; i=t; }
  17.     return j;
  18. }
  19. void UniteSet(int f[],int i,int j){
  20.     int p=FindSet(f,i), q=FindSet(f,j);
  21.     if(p!=q) { f[q]=p; nf++; }
  22. }
  23. /*********************************/
  24. typedef struct DictNode{
  25.     int c;
  26.     char ch;
  27.     struct DictNode *father;
  28.     struct DictNode *next[CN];
  29. }Dict;
  30. int CI(char ch){
  31.     return ch-'a';
  32. }
  33. Dict mem[MEM]; int memp;
  34. Dict* newNode(char ch){
  35.     Dict *p=&mem[memp++]; 
  36.     p->c=0; p->ch=ch;
  37.     p->father=NULL;
  38.     clr(p->next); return p;
  39. }
  40. int Insert(Dict *p,char s[]){
  41.     if(!s[0]){
  42.         if(p->c==0) p->c=++nd;
  43.         d[p->c]++;      //统计单词出现次数 
  44.         return p->c;
  45.     }
  46.     if(p->next[CI(s[0])]==NULL)
  47.         p->next[CI(s[0])]=newNode(s[0]);
  48.     p->next[CI(s[0])]->father=p;
  49.     return Insert(p->next[CI(s[0])],s+1);
  50. }
  51. /*******************************************/
  52. Dict *root;
  53. int main()
  54. {
  55.     int i,j,k,odd;
  56.     char s[20],t[20];
  57.     
  58.     //init
  59.     nd=0; clr(d); memp=0;
  60.     root=newNode(0); nf=0;
  61.     for(i=0;i<M;i++) f[i]=i;
  62.     
  63.     //input
  64.     while(scanf("%s%s",s,t)!=EOF){
  65.         i=Insert(root,s);
  66.         j=Insert(root,t);
  67.         UniteSet(f,i,j);
  68.     }
  69.     
  70.     //judge
  71.     odd=0;
  72.     for(i=1;i<=nd;i++) if(d[i]&1) odd++;
  73.     //output
  74.     if((nf+1==nd||nd==0) && odd<=2) puts("Possible");
  75.     else puts("Impossible");
  76.     return 0;
  77. }

 

 

抱歉!评论已关闭.