poj2513(Colored Sticks)

题目地址:Colored Sticks

 

题目大意:

    给你多个木棒,每个木棒的两头分别着色,使所有木棒首尾排成一条直线,相互接触的端点颜色必须是相同的,问你有没有这种可能性。

 

解题思路:

   先是利用trie树将所给的所有颜色字符串标序。因为是每个木棒只能用一次,简单看成一个木棒的首尾相当于图中的一条连线,将所有数据连通之后,因为每个木棒只能用一次,而且必须都得经过,所以判断是否这个图是否含有无向图的欧拉通路即可。又因为每个木棒不一定在同一集合里,所以需要用并查集来判断无向图是否连通。

 

代码:

  1 #include <algorithm>
  2 #include <iostream>
  3 #include <sstream>
  4 #include <cstdlib>
  5 #include <cstring>
  6 #include <cstdio>
  7 #include <string>
  8 #include <bitset>
  9 #include <vector>
 10 #include <queue>
 11 #include <stack>
 12 #include <cmath>
 13 #include <list>
 14 //#include <map>
 15 #include <set>
 16 using namespace std;
 17 /***************************************/
 18 #define ll long long
 19 #define int64 __int64
 20 #define PI 3.1415927
 21 /***************************************/
 22 const int INF = 0x7f7f7f7f;
 23 const double eps = 1e-8;
 24 const double PIE=acos(-1.0);
 25 const int d1x[]= {0,-1,0,1};
 26 const int d1y[]= {-1,0,1,0};
 27 const int d2x[]= {0,-1,0,1};
 28 const int d2y[]= {1,0,-1,0};
 29 const int fx[]= {-1,-1,-1,0,0,1,1,1};
 30 const int fy[]= {-1,0,1,-1,1,-1,0,1};
 31 /*vector <int>map[N];map[a].push_back(b);int len=map[v].size();*/
 32 /***************************************/
 33 void openfile()
 34 {
 35     freopen("data.in","rb",stdin);
 36     freopen("data.out","wb",stdout);
 37 }
 38 priority_queue<int> qi1;
 39 priority_queue<int, vector<int>, greater<int> >qi2;
 40 /**********************华丽丽的分割线,以上为模板部分*****************/
 41 const int MAX=30;
 42 const int M=250000+1;
 43 struct Trie
 44 {
 45     Trie *next[MAX];  //存储下一层
 46     int v;  //存储到此有多少相同前缀的数目
 47     int count;
 48 };
 49 Trie *root;
 50 int sum;
 51 int d=0;
 52 int d1[M*2];
 53 int pre[M*2];
 54 int creatTrie(char s[])
 55 {
 56     Trie *p,*q;
 57     p=root;
 58     int len=strlen(s);
 59     for(int i=0; i<len; i++)
 60     {
 61         int ce=s[i]-'a';
 62         if (p->next[ce]==NULL)
 63         {
 64             q=(Trie *)malloc(sizeof(Trie));
 65             q->v=1;
 66             for(int j=0; j<MAX; j++)
 67             {
 68                 q->next[j]=NULL;
 69                 q->count=-1;
 70             }
 71             p->next[ce]=q;
 72             p=p->next[ce];
 73         }
 74         else
 75         {
 76             p->v++;
 77             p=p->next[ce];
 78         }
 79     }
 80     p->v=-1;
 81     if (p->count==-1)
 82         p->count=d++;
 83     return p->count;
 84 }
 85 
 86 int dealTrie(Trie *T)
 87 {
 88     if (T==NULL)
 89         return 0;
 90     for(int i=0; i<MAX; i++)
 91         if (T->next[i]!=NULL)
 92             dealTrie(T->next[i]);
 93     free(T);
 94     return 0;
 95 }
 96 int find(int x)
 97 {
 98     if (x!=pre[x])
 99     {
100         pre[x]=find(pre[x]);
101         return pre[x];
102     }
103     return x;
104 }
105 void unionone(int a,int b)
106 {
107     int x=find(a);
108     int y=find(b);
109     if (x!=y)
110         pre[x]=y;
111 }
112 int main()
113 {
114     char s1[20],s2[20];
115     root=(Trie *)malloc(sizeof(Trie));
116     int i,j;
117     for(i=0; i<MAX; i++) //初始化
118     {
119         root->next[i]=NULL;
120         root->count=-1;
121     }
122     for(i=0;i<M;i++)
123         pre[i]=i;
124     memset(d1,0,sizeof(d1));
125     while(scanf("%s %s",s1,s2)!=EOF)
126     {
127         int a=creatTrie(s1);
128         int b=creatTrie(s2);
129         unionone(a,b);
130         d1[a]++;
131         d1[b]++;
132     }
133     int cnt=0,flag=0;
134     for(i=0;i<M*2;i++)
135         if (d1[i]%2)
136             cnt++;
137     if (cnt==2||cnt==0)
138         flag=1;
139     for(i=0;i<d;i++)
140         if (find(0)!=find(i))
141             flag=0;
142     if (flag)
143         printf("Possible\n");
144     else
145         printf("Impossible\n");
146     dealTrie(root);
147     return 0;
148 }
View Code

 

posted @ 2014-08-01 17:53  kinghold  Views(216)  Comments(0Edit  收藏  举报