您的位置:首页 > 其它

POJ-2513 Colored Sticks【并查集+Trie+欧拉路】

2012-04-13 13:09 435 查看
题目链接:http://poj.org/problem?id=2513



题目大意:

有N根木棒,一根木棒有2头,我们把每头涂色(相同或不同),如果2根木棒有相同颜色的一端就可以连接,颜色全部不同就不能连接,现在给你N根木棒以及它们的颜色,问最后能不能链接成1条链。



解题思路:

本质上是一个欧拉路的问题,但是因为颜色是字符串,我们没法简单的处理(用map会超时~。~),所以应该通过一种方法把每个单词转换成一个数字,然后就变成一个典型的欧拉路问题了。

可以使用字典树处理颜色,对每个颜色返回1个值,然后用并查集判断连通图+欧拉路解决即可。

原来写的pre数组是pre[i] = i,优化后变成pre[i] = -1,这样,我们赋值时候可以使用memset,速度加快。然后Find_Set采用递归+路径压缩,insert返回数组下标,字典树采用静态的数组,速度加快。优化后速度由900+ms变为400+ms。



代码如下:

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

#define CLR(arr, what) memset(arr, what, sizeof(arr))
const int N = 15;
const int M = 1000010;

struct Trie
{
	int num;
	Trie* next[26];
}*Head;

char u
, v
;
int num, n, top, total;
bool flag;
int pre[M], in[M];
Trie trie[M];

int Find_Set(int x) //递归+路径压缩
{
	return pre[x] == -1 ? x : (pre[x] = Find_Set(pre[x]));
}

void Make_Set(int x, int y) //无按秩合并
{
	int root1 = Find_Set(x);
	int root2 = Find_Set(y);
	if(root1 != root2)
		pre[root2] = root1;
}

int insert(char str[]) //返回数组下标
{
	Head = &trie[0];
	int len = strlen(str);
	for(int i = 0; i < len; ++i)
	{
		int temp = str[i] - 'a';
		if(Head->next[temp] == NULL)
			Head->next[temp] = &trie[++num];
		Head = Head->next[temp];
	}
	if(Head->num == 0)
		Head->num = top++;
	return Head->num;
}

void init()
{
	num = total = 0; top = 1; flag = true;
	CLR(in, 0); CLR(pre, -1);
	for(int i = 0; i < 2 * n + 2; ++i)
	{
		trie[i].num = 0;
		for(int j = 0; j < 26; ++j)
			trie[i].next[j] = NULL;
	}
}

int main()
{
	int tmp, temp;
	init();
	while(scanf("%s %s", &u, &v) != EOF)
	{
		tmp = insert(u); temp = insert(v);
		in[tmp]++; in[temp]++;
		Make_Set(tmp, temp);
	}
	int root = Find_Set(1);
	for(int i = 1; i < top; ++i) //是否连通+奇度点个数
	{
		if(root != Find_Set(i))
		{
			flag = false;
			break;
		}
		if(in[i] & 1)
			total++;
		if(total > 2)
			break;
	}
	puts(((total == 0 || total == 2) && flag == true) ? "Possible" : "Impossible");
	return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: