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;
}