POJ 2513 Colored Sticks

  给你N个棍子,每个棍子的两端涂有颜色。两个涂有一种颜色的端点可连在一起。

  问这N根棍子是否能连成一条直线。

  可以把每个棍子看成一条边,端点为两个节点。则问题转化成所给的这些端点是否连通,若连通是否存在一笔画的问题,即是否存在欧拉回路。

  并查集+路径压缩 判断图是否连通。

  另在图连通的情况下若不存在度数为奇数的点或有且仅有两个度数为奇数的点,则存在欧拉回路。

  

  1 #include <iostream>
  2 #include <cstdlib>
  3 #include <cstdio>
  4 #include <algorithm>
  5 #include <cstring>
  6 
  7 using namespace std;
  8 
  9 int me[510000];
 10 int degree[510000] = {0};
 11 int ans_color;
 12 
 13 struct Tire
 14 {
 15     Tire *next[26];
 16     int ans;
 17 }*root;
 18 
 19 Tire *creat()
 20 {
 21     Tire * p = (Tire *)malloc(sizeof(Tire));
 22     for(int i = 0;i < 26; i++)
 23         p->next[i] = NULL;
 24     p->ans = -1;
 25     return p;
 26 }
 27 
 28 int ans_odd,ans_sum;
 29 
 30 int insert(Tire *root,char *s)
 31 {
 32     int len = 0;
 33     while(s[len] != '')
 34     {
 35         if(root->next[s[len]-'a'] == NULL)
 36             root->next[s[len]-'a'] = creat();
 37         root = root->next[s[len]-'a'];
 38         ++len;
 39     }
 40     if(root->ans == -1)
 41         root->ans = ans_sum++;
 42     return root->ans;
 43 }
 44 
 45 int find(int x)
 46 {
 47     int j,k,r;
 48     r = x;
 49     while(r != me[r])
 50         r = me[r];
 51     k = x;
 52     while(k != r)
 53     {
 54         j = me[k];
 55         me[k] = r;
 56         k = j;
 57     }
 58     return r;
 59 }
 60 
 61 void merge(int u,int v)
 62 {
 63     int fu = find(u);
 64     int fv = find(v);
 65 
 66     me[fv] = fu;
 67     return ;
 68 }
 69 
 70 int main()
 71 {
 72     char s1[11],s2[11];
 73 
 74     root = creat();
 75 
 76     int i,sum;
 77 
 78     int u,v;
 79 
 80     for(i = 0;i <= 510000; ++i)
 81         me[i] = i;
 82 
 83     ans_odd = 0;
 84     ans_sum = 0;
 85 
 86     while(scanf("%s %s",s1,s2) != EOF)
 87     {
 88         u = insert(root,s1);
 89         v = insert(root,s2);
 90         degree[u]++;
 91         degree[v]++;
 92         merge(u,v);
 93     }
 94 
 95     int pa = find(0);
 96 
 97     for(ans_odd = 0,i = 0,sum = 0;i < ans_sum; i++)
 98     {
 99         if( (degree[i]&1) == 1)
100             ans_odd++;
101 
102         if(me[i] == i)
103             ++sum;
104         
105         if(ans_odd > 2 || sum > 1)
106         {
107             printf("Impossible
");
108             return 0;
109         }
110     }
111 
112     if(ans_sum != 1)
113         printf("Possible
");
114     else
115         printf("Impossible
");
116 
117     return 0;
118 }
View Code
原文地址:https://www.cnblogs.com/zmx354/p/3255445.html