POJ 2513

//#pragma warning (disable:4996)

#include <algorithm>
#include <vector>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>

const int maxVertexCount = 250000 * 2 + 1;

int ancestor[maxVertexCount];
int rank[maxVertexCount];
int colorID;

int degree[maxVertexCount + 1];

void InitializeSet()
{
	for (int i = 0; i < maxVertexCount; ++i)
	{
		ancestor[i] = i;
	}
}


int FindSet(int x)
{
	if (ancestor[x] != x)
		ancestor[x] = FindSet(ancestor[x]);
	return ancestor[x];
}

void UnionSet(int lhs, int rhs)
{
	int lhsParent = FindSet(lhs);
	int rhsParent = FindSet(rhs);
	if (rank[lhsParent] > rank[rhsParent])
	{
		ancestor[rhsParent] = lhsParent;
	}
	else
	{
		ancestor[lhsParent] = rhsParent;
		if (rank[lhsParent] == rank[rhsParent])
		{
			++rank[rhsParent];
		}
	}
}

struct TrieNode
{
	bool flag;
	int id;
	TrieNode* next[27];

	TrieNode()
	{
		flag = false;
		id = 0;
		std::memset(static_cast<void*>(next), 0, sizeof(next));
	}
};


TrieNode* root = new TrieNode();

int GetIndex(const char* str)
{
	TrieNode* nodePtr = root;
	for (int i = 0; str[i]; ++i)
	{
		int index = str[i] - 'a';
		if (!nodePtr->next[index])
		{
			nodePtr->next[index] = new TrieNode();
		}
		nodePtr = nodePtr->next[index];
	}
	if(!nodePtr->flag)
	{
		nodePtr->flag = true;
		nodePtr->id = ++colorID;
	}
	return nodePtr->id;
}


int main()
{
	InitializeSet();
	char firstColor[11] = { 0 }, secondColor[11] = { 0 };
	std::ios::ios_base::sync_with_stdio(false);
	while (std::cin >> firstColor >> secondColor)
	{
		int firstColorIndex = GetIndex(firstColor);
		int secondColorIndex = GetIndex(secondColor);
		++degree[firstColorIndex];
		++degree[secondColorIndex];
		UnionSet(firstColorIndex, secondColorIndex);
	}
	int s = FindSet(1);
	int oddDegreeCount = 0;
	bool isPossible = true;
	for (int i = 1; i < colorID; ++i)
	{
		if (degree[i] & 1) ++oddDegreeCount;
		if (oddDegreeCount > 2)
		{
			isPossible = false;
			break;
		}
		if (FindSet(i) != s)
		{
			isPossible = false;
			break;
		}
	}
	if (oddDegreeCount == 1) isPossible = false;
	if (isPossible)
	{
		std::printf("%s\n", "Possible");
	}
	else
	{
		std::printf("%s\n", "Impossible");
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值