POJ 2513 Colored Sticks(欧拉回路判断+字典树Trie+并查集)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/sdz20172133/article/details/87898051

Colored Sticks

Time Limit: 5000MS   Memory Limit: 128000K
Total Submissions: 40272   Accepted: 10463

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

Hint

Huge input,scanf is recommended.

Source

The UofA Local 2000.10.14

题意:

给一些木棒,木棒两端都涂上颜色,求是否能将木棒首尾相接,连成一条直线,要求不同木棒相接的一边必须是相同颜色的

分析:

典型的判断欧拉路和欧拉回路问题,关键映射map竟然超时,用字典树就过来

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<queue>
#include<map>
using namespace std;
const int N=260000;
 
int n, m;
int f[N*2],degree[N*2];//记录第i点的度数
const int maxnode=5000000+1000;
const int sigma_size=26;
int cnt;//记录当前已经读入了cnt个不同的颜色了
struct Trie
{
    int ch[maxnode][sigma_size];
    int val[maxnode];//单词节点的val才非0,且val[i]表示的是该单词节点的编号
    int sz;
    void init()
    {
        sz=1;
        memset(ch[0],0,sizeof(ch[0]));
        val[0]=0;
    }
    int insert(char *s)
    {
        int n=strlen(s),u=0;
        for(int i=0;i<n;i++)
        {
            int id=s[i]-'a';
            if(ch[u][id]==0)
            {
                ch[u][id]=sz;
                val[sz]=0;
                memset(ch[sz],0,sizeof(ch[sz]));
                sz++;
            }
            u=ch[u][id];
        }
        if(val[u]==0)//新颜色
            val[u]=++cnt;
        return val[u];
    }
}trie;
int find_(int x)
{
	if(f[x]==-1)	return x;
	return f[x] = find_(f[x]);
}
void merge_(int x, int y)
{
	int t1, t2;
	//cout<<f[x]<<endl;
	t1 = find_(x); 
	t2 = find_(y);
	if (t1 != t2)	f[t2] = t1;
	else return;
}
int isEuler()
{
	int cnt=0;
	for (int i = 1; i <= n; i++)
		{
			if (degree[i] & 1)	
			cnt++;
			if(cnt>2) return 0;
		}
		
	if(cnt==2||cnt==0) return 1;
	return 0;
}
int isconnect()
{
	int cnt = 0;
	int ff=find_(1);
	for (int i=2; i <= n; i++)
	{
		if (find_(i)!=ff)
		return 0;
	}
	return 1;
}
int main()
{
	    memset(f,-1,sizeof(f));
		memset(degree, 0, sizeof(degree));
		cnt=0;
		trie.init();
		char t1[100],t2[100];
		n=1;
		//int i=0;
		while(scanf("%s%s",t1,t2)!=EOF)
		{
			int i=trie.insert(t1);//尝试插入新颜色
            int j=trie.insert(t2);
		
			
			//cout<<mapp[t1]<<" "<<mapp[t2]<<endl;
			degree[i]++;
			degree[j]++;
			
			merge_(i,j);
			  //i++;
			//if(i==5) break;
		}
		n=cnt;
		//cout<<"sss"<<endl;
		if(isconnect()&&isEuler())	
		printf("Possible");
		else
		printf("Impossible");
	return 0;
}

猜你喜欢

转载自blog.csdn.net/sdz20172133/article/details/87898051
今日推荐