• poj 2513 Colored Sticks


    Description

    You are given a bunch of wooden sticks. Each endpoint of each stick is colored with some color. Is it possible to align the sticks in a straight line such that the colors of the endpoints that touch are of the same color?

    Input

    Input is a sequence of lines, each line contains two words, separated by spaces, giving the colors of the endpoints of one stick. A word is a sequence of lowercase letters no longer than 10 characters. There is no more than 250000 sticks.

    Output

    If the sticks can be aligned in the desired way, output a single line saying Possible, otherwise output Impossible.

    Sample Input

    blue red
    red violet
    cyan blue
    blue magenta
    magenta cyan
    

    Sample Output

    Possible

    Hint

    Huge input,scanf is recommended.

    Source

     
    有一端颜色相同的可以接到一块,那么就默认颜色相同的拼到一起了,然后每行给出两个颜色,对两个颜色进行合并,看看最后是否是一个连通图,如果是连通图了,还得拍成一行,也就是一笔走完所有点,就是判断欧拉图,奇数度的点最多两个,注意有坑,如果一行数据也没有,也是Possible。
    这里用字典树,记录每种颜色,返回对应的下标,然后进行并查集合并,以此判断是否为连通图。记录每种颜色出现次数,判断他的度数的奇偶性。
    代码:
    #include <iostream>
    #include <cstdio>
    #include <sstream>
    #include <cstring>
    #define MAX 2000005
    using namespace std;
    int pos,pos1;
    int trie[MAX][26],num[MAX],to[MAX];
    int f[MAX];
    int odd,root;
    int Insert(char *s) {
        int i = 0,c = 0;
        while(s[i]) {
            int d = s[i] - 'a';
            if(!trie[c][d]) trie[c][d] = ++ pos;
            c = trie[c][d];
            i ++;
        }
        if(!to[c]) {
            to[c] = ++ pos1;
            f[pos1] = pos1;
        }
        num[to[c]] ++;
        return to[c];
    }
    int getf(int x) {
        return f[x] == x ? f[x] : f[x] = getf(f[x]);
    }
    void Union(int x,int y) {
        int xx = getf(x);
        int yy = getf(y);
        if(xx != yy) {
            f[xx] = yy;
        }
    }
    int main() {
        char s[20],t[20];
        while(~scanf("%s%s",s,t)) {
            int d = Insert(s);
            int e = Insert(t);
            Union(d,e);
        }
        for(int i = 1;i <= pos1;i ++) {
            if(getf(i) == i) root ++;
            if(num[i] % 2) odd ++;
        }
        if(root <= 1 && odd <= 2)puts("Possible");
        else puts("Impossible");
    }
  • 相关阅读:
    exec系列函数和system函数
    fork函数相关总结
    文件的内核结构file和dup实现重定向
    进程基本概述
    fcntl 函数与文件锁
    文件的属性
    目录的操作
    文件的读取写入
    文件的打开关闭
    浅谈原始套接字 SOCK_RAW 的内幕及其应用(port scan, packet sniffer, syn flood, icmp flood)
  • 原文地址:https://www.cnblogs.com/8023spz/p/9606905.html
Copyright © 2020-2023  润新知