zoukankan      html  css  js  c++  java
  • POJ2513 Colored Sticks(欧拉)

    题目链接

    题目大意:

    给很多木棍,两端被涂了颜色。任意两根木棍的相同颜色处可以拼接在一起,问有没有可能将所有的木棍都连起来,成一条直线?

    分析:

    考点,欧拉道路。

    将一根木棍看成一条边,两端的颜色看成两个点,问题成了,能否从无向图的一个结点出发走出一条道路,每条边恰好经过一次。

    求法:

    如果一个无向图连通的,且最多有两个奇点(奇点指的是度数是奇数的点),则一定存在欧拉道路。

    是否连通可以通过并查集来求。

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <cmath>
    #include <string>
    using namespace std;
    
    const int maxn = 500000+10+10;
    
    int deg[maxn], cm, cn, p[maxn];
    
    struct node {
        struct node *next[26];
        int num;
    }mem[250000*40+10];
    
    node *create() {
        for(int i=0; i<26; i++) {
            mem[cm].next[i] = NULL;
        }
        mem[cm].num = 0;
        return &mem[cm++];
    }
    
    int get_num(node *&root, char s[]) {
        int len = strlen(s);
        node *p;
    
        if(!root) root = create();
    
        p = root;
        for(int i=0; i<len; i++) {
            int k = s[i] - 'a';
            if(!p->next[k]) p->next[k] = create();
            p = p->next[k];
        }
    
        if(!p->num) p->num = cn++;
        return p->num;
    }
    
    int find(int x) { return p[x] == x ? p[x] : (p[x] = find(p[x])); }
    
    void Union(int x, int y) {
        x = find(x), y = find(y);
        if(x != y) p[x] = y;
    }
    
    int main(){
        int u, v;
        char s1[20], s2[20];
        node *root = NULL;
    
        cm = 0, cn = 1;
    
        memset(deg, 0, sizeof(deg));
    
        for(int i=1; i<maxn; i++) p[i] = i;
    
        while(scanf("%s %s", s1, s2) == 2) {
            u = get_num(root, s1);
            v = get_num(root, s2);
    
            deg[u]++;
            deg[v]++;
    
            Union(u, v);
        }
    
        int pn= 0;
        bool flag = true;
    
        int e = find(1);
    
        for(int i=1; i<cn; i++) {  //从1开始编号
            if(deg[i] % 2 != 0) {
                pn++;
            }
    
            if(pn > 2 || find(i) != e) {
                flag = false; break;
            }
        }
    
        if(flag) printf("Possible
    ");
        else printf("Impossible
    ");
    
        return 0;
    }
  • 相关阅读:
    CF733F
    P4826
    洛谷P2687 & P1108
    CF42A
    洛谷P1858
    CF1428C
    洛谷P4981
    树形DP
    背包六讲(也不知道为啥就是六个 $QwQ$)
    2020
  • 原文地址:https://www.cnblogs.com/tanhehe/p/3239945.html
Copyright © 2011-2022 走看看