POJ 2513 Colored Sticks(hash + 欧拉道路)

题目链接:点击打开链接

题意:n个木棍, 两端有颜色, 相同颜色可以链接, 问你最终能否形成一条线段。

思路:典型的欧拉道路, 成立的条件是 1. 图联通 。 2. 度为奇数的点不能超过2个。 用map超时了, 可以用hash水过去。

细节参见代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<stack>
#include<bitset>
#include<cstdlib>
#include<cmath>
#include<set>
#include<list>
#include<deque>
#include<map>
#include<queue>
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
using namespace std;
typedef long long ll;
typedef long double ld;
const ld eps = 1e-9, PI = 3.1415926535897932384626433832795;
const int mod = 1000000000 + 7;
const int INF = 0x3f3f3f3f;
// & 0x7FFFFFFF
const int seed = 131;
const ll INF64 = ll(1e18);
const int maxn = 500000 + 10;
const int hashsize = 1000007;
int T,n,m,p[hashsize + 10],in[hashsize + 10];
int res, cnt, hehe[hashsize + 10];
char s[22],s2[22];
int _find(int x) { return p[x] == x ? x : p[x] = _find(p[x]); }
int _hash(char *s) {
    int len = strlen(s), v = 1;
    for(int i=0;i<len;i++) v = (v * 37 + s[i] - 'a') % hashsize;
    return v;
}
int main() {
    int cnt = 0;
    for(int i=0;i<hashsize;i++) p[i] = i, hehe[i] = 0;
    while(~scanf("%s%s",s,s2)) {
        int a = _hash(s);
        int b = _hash(s2);
        if(!hehe[a]) hehe[a] = 1;
        if(!hehe[b]) hehe[b] = 1;
        in[a]++; in[b]++;
        int x = _find(a);
        int y = _find(b);
        if(x != y) {
            p[x] = y;
        }
    }
    bool ok = true;
    for(int i = 0; i < hashsize; i++) if(hehe[i] && _find(i) == i) ++cnt;
    if(cnt > 1) ok = false;
    int res = 0;
    for(int i = 1; i < hashsize; i++) {
        if(hehe[i]) {
            if(in[i] & 1) ++res;
        }
    }
    if(res > 2) ok = false;
    if(ok) printf("Possible\n");
    else printf("Impossible\n");
    return 0;
}


你可能感兴趣的:(hash,poj,ACM-ICPC,欧拉道路)