题意:每次给你一根木棒,木棒首尾有两个单词,两根木棒单词一样的位置可以相连,问最后是否可以连成一根木棒。
思路:一开始直接用MAP来HASH,然后就T了。
后来发现其实每个单词最后10个字母,直接用TRIE来存每个单词查询的时候复杂度其实差不多也是O(1)的。
还要注意要用并查集来判图是否连通。
蛮综合的一道题。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string>
#include <cmath>
#include <cstring>
#include <queue>
#include <set>
#include <vector>
#include <stack>
#include <map>
#include <iomanip>
#define PI acos(-1.0)
#define Max 2505
#define inf 1<<28
#define LL(x) ( x << 1 )
#define RR(x) ( x << 1 | 1 )
#define REP(i,s,t) for( int i = ( s ) ; i <= ( t ) ; ++ i )
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a))
#define mp(a,b) make_pair(a,b)
#define PII pair<int,int>
using namespace std;
#define N 1000005
char a[N] , b[N] ;
int in[N] , out[N] ;
struct trie{
int next[26] ;
int count ;
void init(){
mem(next ,0) ;
count = 0 ;
}
} T[N] ;
int num ;
int cnt ;
void build(char *a ){
int l = strlen(a) ;
int p = 0 ;
for (int i = 0 ; i < l ; i ++ ){
int tt = a[i] - 'a' ;
if(T[p].next[tt] == 0){
T[p].next[tt] = ++ num ;
T[num].init() ;
}
p = T[p].next[tt] ;
}
if(!T[p].count)T[p].count = ++ cnt ;
}
int find(char *a){
int l = strlen(a) ;
int p = 0 ;
for (int i = 0 ; i < l ;i ++ ){
p = T[p].next[a[i] - 'a'] ;
}
return T[p].count ;
}
int fa[N] ;
int findU(int x){
return fa[x] == x ? x : fa[x] = findU(fa[x]) ;
}
void Union(int a ,int b){
a = findU(a) ;
b = findU(b) ;
if(a == b)return ;
if(a > b)fa[a] = b ;
else fa[b] = a ;
}
int main() {
cnt = 0 ;
num = 0 ;
for (int i = 0 ; i < N ;i ++ )fa[i] = i ;
while(scanf("%s%s",a ,b) != EOF){
build(a) ;
build(b) ;
int x = find(a) ;
int y = find(b) ;
Union(x ,y) ;
in[x] ++ ;
in[y] ++ ;
}
int sum1 = 0 ;
for (int i = 1 ;i <= cnt ;i ++ ){
if(i == findU(i))sum1 ++ ;
}
int sum = 0 ;
for (int i = 1 ; i <= cnt ; i ++ ){
if(in[i] & 1)sum ++ ;
}
if(((sum == 2 || sum == 0 )&& sum1 == 1 )|| (!num))puts("Possible") ;//SB掉了,一开始以为木棒不可以组成欧拉回路,就没判sum = 0的情况。其实木棒可以首尾颜色一样的
else puts("Impossible") ;
return 0 ;
}