POJ 2513 Colored Sticks (字典樹,並查集,歐拉路徑組合題)




Description

You are given a bunch of wooden sticks. Each endpoint of each stick is colored with some color. Is it possible to align the sticks in a straight line such that the colors of the endpoints that touch are of the same color?

Input

Input is a sequence of lines, each line contains two words, separated by spaces, giving the colors of the endpoints of one stick. A word is a sequence of lowercase letters no longer than 10 characters. There is no more than 250000 sticks.

Output

If the sticks can be aligned in the desired way, output a single line saying Possible, otherwise output Impossible.

Sample Input

blue red
red violet
cyan blue
blue magenta
magenta cyan

Sample Output

Possible

火柴有兩個端點,只要顏色一樣就可以連在一起,要判斷能否把所有火柴首尾相連
把每個火柴當作一條邊,所有火柴連接起來當作一個無向圖,只要無向圖能形成歐拉路徑則輸出“Possible”
連通的無向圖  有歐拉路徑的充要條件是:中奇頂點(連接的邊數量爲奇數的頂點)的數目等於0或者2
那我們記錄每個節點的邊數即可,至於節點可以把不同顏色當作不同的節點,同樣的顏色當作同樣的節點,用字典樹輔助判斷,每次只要是新的顏色就映射爲一個新的數字即可
至於整體是否連通用並查集記錄即可


#include<stdio.h>
#include<string.h>
#include<memory.h>

struct Node
{
	Node *next[26];
	int cnt;//記錄單詞末尾標記,標記單詞映射的數字
	Node()
	{
		for (int i = 0; i<26; i++) next[i] = NULL;
		cnt = -1;
	}
};

Node root;
int color[500001];
int father[500001];

void insert(char *str, int num)
{
	Node *p = &root, *q;
	int len = strlen(str);
	int id;
	for (int i = 0; i<len; i++)
	{
		id = str[i] - 'a';
		if (p->next[id] == NULL)
		{
			q = new Node;
			p->next[id] = q;
			p = q;
		}
		else
		{
			p = p->next[id];
		}
		if (i == len - 1) p->cnt = num;
	}
}

int find(char *str)
{
	int len = strlen(str);
	Node *p = &root;
	int id;
	for (int i = 0; i<len; i++)
	{
		id = str[i] - 'a';
		p = p->next[id];
		if (p == NULL) return -1;
	}
	return p->cnt;
}

int findfa(int a)
{
	return father[a] == a ? a : findfa(father[a]);
}

int main()
{
	char str1[11], str2[11];
	int num = 0;
	int endnum1, endnum2;
	memset(color, 0, sizeof(color));
	while (scanf("%s%s", str1, str2) != EOF)
	{
		if (strcmp(str1, str2) == 0) continue;//首尾顏色一樣可以當作不存在
		endnum1 = find(str1);
		if (endnum1 == -1)
		{
			insert(str1, num);
			father[num] = num;
			endnum1 = num;
			num++;
		}
		color[endnum1]++;

		endnum2 = find(str2);
		if (endnum2 == -1)
		{
			insert(str2, num);
			father[num] = num;
			endnum2 = num;
			num++;
		}
		color[endnum2]++;
		father[findfa(endnum1)] = father[findfa(endnum2)];
	}
	if (num == 0)
	{
		printf("Possible\n");
		return 0;
	}
	int jdflag = 0, ltflag = 1;
	int i;
	for (i = 0; i<num - 1; i++)
	{
		if (findfa(i) != findfa(i + 1))
		{
			ltflag = 0;
			break;
		}
		if (color[i] % 2 == 1) jdflag++;
	}
	if (color[i] % 2 == 1) jdflag++;
	if (ltflag == 1 && (jdflag == 0 || jdflag == 2)) printf("Possible\n");
	else printf("Impossible\n");
	return 0;
}

發佈了29 篇原創文章 · 獲贊 4 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章