您的位置:首页 > 其它

poj 2513 Colored Sticks

2013-05-06 12:28 190 查看
点击打开链接poj2513

思路: hash+并查集+欧拉路

分析:

1 题目要求给定n个木棒是否可以组成一个满足要求的字符串

2 很明显的判断无向图是否是半欧拉图,首先先判断是否是单连通这一点可以利用并查集,然后在去判断是不是最多两个点的度数为奇数

3 最后一个问题就是怎么把字符串映射成整数,如果利用map肯定是超时的,那么这里就要用到hash,由于这题的数据比较弱我没有处理冲突也过了

代码:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

const int N = 15;
const int MAXN = 500010;
const int MOD = 500003;

char str
;
int cnt , father[MAXN];
int hash[MAXN] , degree[MAXN];
bool vis[MAXN];

void init(){
cnt = 1;
memset(hash , 0 , sizeof(hash));
memset(degree , 0 , sizeof(degree));
memset(vis , false , sizeof(vis));
for(int i = 1 ; i < MAXN ; i++)
father[i] = i;
}

int find(int x){
if(x != father[x])
father[x] = find(father[x]);
return father[x];
}

int Hash(char* s){
int sum = 0;
while(*s)
sum = (*s++)+(sum<<6)+(sum<<16)-sum;
return (sum&0x7FFFFFFF) % MOD;
}

int getHash(int x){
if(!hash[x])
hash[x] = cnt++;
return hash[x];
}

bool isOk(){
int root;
for(int i = 1 ; i <= cnt ; i++){
if(vis[i]){
root = find(i);
break;
}
}
for(int i = 1 ; i <= cnt ; i++)
if(vis[i] && find(i) != root)
return false;
int num = 0;
for(int i = 1 ; i <= cnt ; i++)
if(degree[i]&1)
num++;
return num <= 2;
}

int main(){
init();
while(scanf("%s" , str) != EOF){
int x = Hash(str);
x = getHash(x);
scanf("%s" , str);
int y = Hash(str);
y = getHash(y);
vis[x] = vis[y] = true;
degree[x]++;
degree[y]++;
father[find(x)] = find(y);
}
if(isOk())
puts("Possible");
else
puts("Impossible");
return 0;
}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: