POJ 2513 Colored Sticks 解题报告 字典树 并查集 欧拉通路

POJ 2513 Colored Sticks 解题报告

解题思路:由欧拉通路的结论,首先我们要统计出入度,如果各个颜色各自的度数和中只有1个是奇数或者有3个及以上为奇数,那么就不可能,那么如何统计度数呢?建立字典树,如果到达一个颜色字符串的末尾,这个颜色的度数+1。通过以上条件后进行下一步判断,如何判断木条能连成一根呢?用并查集,除了顶端颜色的最上级就是其自身外,其他颜色的最上级都应该是顶端颜色,统计并查集中颜色等于自身的次数,如果超过1,就是不可能。通过以上全部条件就能连接成一根木条了。
在这里插入图片描述

#include<iostream>
#include<math.h>
#include<iomanip>
#include<algorithm>
#include<iostream>
#include<math.h>
#include<iomanip>
#include<algorithm>
#include<queue>
#include<cstring>
#include<string>
#include<map>
#include<stack>
#include<stdio.h>
#include<cstdio>
#include<stdlib.h>
#include<fstream>
#include<iomanip>
#pragma warning(disable:4996)
#define INF 0x3f3f3f3f
#define ll long long
#define PI acos(-1.0)
const int N = 500010;
const int maxn = 1e9;
using namespace std;
struct trie {
	bool flag;//标记字符串是否到达末尾
	int index;
	trie* next[27];
	trie() {
		flag = false;
		index = 0;
		memset(next, 0, sizeof(next));
	}
}root;
int color;
int degree[N];
int ancestor[N];
int find(int x)//寻找x最上级
{
	if (ancestor[x] != x)
		ancestor[x] = find(ancestor[x]);
	return ancestor[x];
}
void union_set(int a, int b)//使a和b的上级相同
{
	int pa = find(a);
	int pb = find(b);
	ancestor[pb] = pa;
	return;
}
int ha(char* s)
{
	trie* p = &root;
	int len = 0;
	while(s[len]!='\0')//建立字典树
	{
		int index = s[len++] - 'a';
		if (!p->next[index])
			p->next[index] = new trie;
		p=p->next[index];
	}
	//循环结束后已到达字符串末尾
	if (p->flag)
		return p->index;
	else
	{
		p->flag = true;
		p->index = ++color;//每一种颜色都有自己的标号
		return p->index;
	}
}
int main()
{
	memset(degree, 0, sizeof(degree));
	color = 0;
	for (int i = 1; i <= N; i++)
	{
		ancestor[i] = i;//一开始并查集中元素的最上级都是自己
	}
	char a[11], b[11];
	while (~scanf("%s %s",&a,&b))
	{
		int i = ha(a);
		int j = ha(b);
		degree[i]++;//统计度数,出入度一起算
		degree[j]++;
		union_set(i, j);
		memset(a, 0, sizeof(a));
		memset(b, 0, sizeof(b));
	}
	int num = 0;
	int cnt = 0;
	for (int i = 1; i <= color; i++)
	{
		if (degree[i] % 2 == 1)
			num++;
		if (num > 2)
		{
			printf("Impossible\n");
			return 0;
		}
		if (ancestor[i]==i)
		{
			cnt++;
		}
		if (cnt > 1)
		{
			printf("Impossible\n");
			return 0;
		}
	}
	if (num == 1)
		printf("Impossible\n");
	else
		printf("Possible\n");
}



发布了64 篇原创文章 · 获赞 0 · 访问量 1447

猜你喜欢

转载自blog.csdn.net/weixin_45566331/article/details/104759678
今日推荐