(POJ) 2513 Colored Sticks (字典树/map+并查集+欧拉路径)

传送门

题目大意:给你两段有颜色的木棒,只有相同的颜色才能连接起来,问你最后给你的木棒最后能不能拼成一根长木棒。

解题思路:这里字典树只是返回了不同颜色的编号,用map<string,int>也是可以的,我们可以记录每个颜色的度,一个木棒的两个颜色可以相连,所以这里可以用并查集将不同的颜色并起来,最后如果,有颜色的祖先和其他不一样,那肯定不能连起来,反之那就要判断欧拉路径 了,如果奇数度的点为0或者2,那这个图就可以一笔走完,即可以连接成一根木棒。

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<string>
#include<cstring>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<cmath>
#include<sstream>
using namespace std;
typedef long long ll;
const ll inf=0x3f3f3f3f;
const int maxn=2e6+5;
int tree[maxn][30],sum[maxn];
int vis[maxn],num[maxn];
int tot=0,cnt=0;
int f[maxn],r[maxn];
int add(char *s) {
	int root=0,id,len=strlen(s);
	for(int i=0; i<len; ++i) {
		id=s[i]-'a';
		if(!tree[root][id])	tree[root][id]=++tot;
		root=tree[root][id];
	}
	if(!vis[root])	vis[root]=++cnt;
	return vis[root];
}
void init() {
	for(int i=0; i<maxn; ++i) {
		f[i]=i;
		r[i]=0;
	}
}
int find(int x) {
	if(x=f[x])	return f[x];
	else return f[x]=find(f[x]);
}
void unite(int x,int y) {
	x=find(x);
	y=find(y);
	if(x==y)	return ;
	if(r[x]<r[y])	f[x]=y;
	else {
		f[y]=x;
		if(r[x]==r[y])	r[y]++;
	}
}
char s1[20],s2[20];
int main() {
	int tp1,tp2;
	init();
	while(scanf("%s%s",s1,s2)!=EOF) {
		tp1=add(s1);
		tp2=add(s2);
		num[tp1]++;
		num[tp2]++;
		unite(tp1,tp2);
	}
	int flag=find(1),tt=0;
	for(int i=1; i<=cnt; ++i) {
		if(num[i]%2)	tt++;
		if(find(i)!=flag) {
			cout<<"Impossible"<<endl;
			return 0;
		}
	}
	if(tt==0||tt==2)	cout<<"Possible"<<endl;
	else	cout<<"Impossible"<<endl;
	
	return 0;
}




 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值