题目的大意就是一根木棍两端涂上颜色,然后要把所有的木棍连成一根木棍,然后两根木棍能合并的前提是,连在一起的两端是同样一种颜色,然后这个额就很好理解,是一边画问题,求是否有欧拉路出现就好。
无向图有欧拉路的条件:
1.有0个或者2个点的度数为奇数。
2.图是一个连通图。
然后判断图连通,就是运用并查集的方法,每次合并一条边的两个顶点,最终一个连通图会合并成一个顶点,一个非连通图会合并成多个顶点,然后还要用路径压缩的方法,压缩一下路径。
然后查找每一个单词的索引,由于数据量比较大,map可能比较慢,运用Trie树进行索引查找。
题目有一个坑点是,可能里面有空数据,还要输出Possible。
#include "stdio.h"
#include "string.h"
#include "math.h"
#include <string>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <algorithm>
#include <iostream>
using namespace std;
#define MAXM 1
#define MAXN 1
#define max(a,b) a > b ? a : b
#define min(a,b) a < b ? a : b
#define Mem(a,b) memset(a,b,sizeof(a))
int Mod = 1000000007;
double pi = acos(-1.0);
double eps = 1e-6;
typedef struct{
int f,t,w,next;
}Edge;
Edge edge[MAXM];
int head[MAXN];
int kNum;
void addEdge(int f, int t, int w)
{
edge[kNum].f = f;
edge[kNum].t = t;
edge[kNum].w = w;
edge[kNum].next = head[f];
head[f] = kNum ++;
}
char s1[15], s2[15];
int father[500005];
int indree[500005];
struct Node{
bool flag;
int id;
struct Node *next[27];
Node(){
flag = false;
id = -1;
Mem(next, NULL);
}
};
int find(int x){
int s = x;
while( father[x] != x ) x = father[x];
for(int p = s; p != x; p = s){
s = father[p];
father[p] = x;
}
return x;
}
void Union(int x, int y){
if( x < y ){
father[y] = x;
}
else
father[x] = y;
}
void solve(){
kNum = 0;
Mem(indree,0);
struct Node* root = new struct Node;
int id1, id2;
while( scanf("%s %s", s1, s2) != EOF ){
// getchar();
struct Node *p = root;
for(int i = 0; s1[i] != 0; i ++){
if( p->next[s1[i] - 'a'] == NULL ){
p->next[s1[i] - 'a'] = new struct Node;
}
p = p->next[s1[i] -'a'];
}
if( !p->flag ){
p ->flag = true;
p ->id = kNum ++;
father[p->id] = p->id;
}
id1 = p->id;
p = root;
for(int i = 0; s2[i] != 0; i ++){
if( p->next[s2[i] - 'a'] == NULL ){
p->next[s2[i] - 'a'] = new struct Node;
}
p = p->next[s2[i] -'a'];
}
if( !p->flag ){
p ->flag = true;
p ->id = kNum ++;
father[p->id] = p ->id;
}
id2 = p ->id;
indree[id1] ++, indree[id2] ++;
id1 = find(id1);
id2 = find(id2);
if( id1 != id2 ){
Union(id1, id2);
}
}
int num = 0;
int s = find(0);
for(int i = 0; i < kNum; i ++){
if( indree[i] % 2 )
num ++;
if( num > 2 ){
printf("Impossible\n");
break;
}
if( find(i) != s ){
printf("Impossible\n");
break;
}
if( i == kNum - 1 ){
if( num == 1 ){
printf("Impossible\n");
}
else{
printf("Possible\n");
}
}
}
if( kNum == 0 ){
printf("Possible\n");
}
}
int main()
{
// freopen("d:\\test.txt", "r", stdin);
solve();
return 0;
}