POJ 2513

并查集Union-Set: 使用rank数组

Trie树

欧拉图

#include <iostream>

const int MAXN = 500003;
int N;

int pre[MAXN];
int rank[MAXN];
int deg[MAXN];

struct trie
{
    int color;
    trie* next[26];
    trie()
    {
        color = 0;
        memset(next, 0, sizeof(next));
    }
}*root;

int insert(trie* p, char str[])
{
	for(int i = 0; i < (int)strlen(str); i++)
	{
		int s = str[i] - 'a';
		if(p->next[s] == NULL)
			p->next[s] = new trie;
		p = p->next[s];

		if(i == (int)strlen(str) - 1)
		{
			if(p->color == 0)
				p->color = ++N;
			++deg[p->color];
			return p->color;
		}
	}
	return 0;
}

void init()
{
	for(int i = 1; i < MAXN; i++)
	{
		pre[i] = i;
		rank[i] = 0;
	}
}

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

void unionOp(int x, int y)
{
	if(rank[x] < rank[y])
		pre[x] = pre[y];
	else if(rank[x] > rank[y])
		pre[y] = pre[x];
	else
	{
		pre[y] = pre[x];
		rank[x]++;
	}
}

bool isConnected()
{
	for(int i = 2; i <= N; i++)
		if(find(i) != find(i - 1))
			return false;

	return true;
}

int main()
{
	char c1[11], c2[11];
	int x, y, oddDeg = 0;;
	N = 0;
	root = new trie;

	memset(deg, 0, sizeof(deg));
	init();
	while(scanf("%s%s", c1, c2) != EOF)
	{
		x = insert(root, c1);
		y = insert(root, c2);
		unionOp(x, y);
	}

	if(!isConnected())
	{
		printf("Impossible\n");
		return 0;
	}

	for(int i = 1; i <= N; i++)
	{
		if(deg[i] % 2 != 0)
			++oddDeg;
		if(oddDeg > 2)
		{
			printf("Impossible\n");
			return 0;
		}
	}

	printf("Possible\n");

	return 0;
}


你可能感兴趣的:(c,struct,null,insert)