POJ2513 Colored Sticks 无向图欧拉通路判定+字符串hash

题意:给定许多根棍子,这些棍子两头有不同的颜色,问是否能够存在这样一中组合方式使得所有的棍子首尾相连。

解法:这题使用map处理字符串超时了,所以自己写了一个插值取模的字符串hash。只要判定图是否连通和度为奇数是否大于2个即可,不可能出现奇数个度为奇数的点。

代码如下:

#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <map>
#include <string>
#include <vector>
using std::vector;

typedef unsigned long long int64;
const int MOD = 250007;
const int64 T = 37;
char sa[15], sb[15];
int deg[500005];
int set[500005];
int head[250010];
int64 _pow[15];

vector<int>v;

struct Edge {
    int tag, next;
    int64 key;
}e[500005];
int idx, tag;


int find(int x) {
    return set[x] = x == set[x] ? x : find(set[x]);    
}

void merge(int a, int b) {
    set[a] = b;
}

void insert(int64 key, int tg) {
    int pos = key % MOD;
    e[idx].key = key;
    e[idx].tag = tg;
    e[idx].next = head[pos];
    head[pos] = idx++;
}

int64 getkey(char str[]) {
    int64 key = 0;
    int len = strlen(str);
    for (int i = 0; i < len; ++i) {
        key += (str[i]-'a') * _pow[i];
    }
    return key;
}

void hash(char str[]) {
    int64 key = getkey(str);
    insert(key, tag++);
}

int get(char str[]) {
    int64 key = getkey(str);
    int pos = key % MOD;
    for (int i = head[pos]; i != -1; i = e[i].next) {
        if (e[i].key == key) {
            return e[i].tag;
        }
    }
    return -1;
}

int main() {
    int ok = 0;
    for (int i = 0; i < 500000; ++i) {
        set[i] = i;
    }
    _pow[0] = 1;
    for (int i = 1; i <= 10; ++i) {
        _pow[i] = T * _pow[i-1];
    }
    memset(head, 0xff, sizeof (head));
    while (scanf("%s %s", sa, sb) != EOF) {
        if (get(sa) == -1) {
            hash(sa);
        } 
        if (get(sb) == -1) {
            hash(sb);
        }
        int a = get(sa), b = get(sb);
        ++deg[a], ++deg[b];
        merge(find(a), find(b));
    }
    for (int i = 0; i < tag; ++i) {
        if (set[i] == i) {
            ++ok;
        }
        if (deg[i] & 1) {
            v.push_back(i);
        }
    }
    if (ok != 1 && ok) {
        puts("Impossible");
        return 0;
    } else if (v.size() > 2){
        puts("Impossible");
    } else {
        puts("Possible");
    }
    return 0;
}
原文地址:https://www.cnblogs.com/Lyush/p/2983910.html