洛谷P1333 瑞瑞的木棍

传送门

题目描述

瑞瑞有一堆的玩具木棍,每根木棍的两端分别被染上了某种颜色,现在他突然有了一个想法,想要把这些木棍连在一起拼成一条线,并且使得木棍与木棍相接触的两端颜色都是相同的,给出每根木棍两端的颜色,请问是否存在满足要求的排列方式。

例如,如果只有 2 根木棍,第一根两端的颜色分别为 red, blue,第二根两端的颜色分别为 red, yellow,那么 blue—red | red----yellow 便是一种满足要求的排列方式。

输入格式

输入有若干行,每行包括两个单词,表示一根木棍两端的颜色,单词由小写字母组成,且单词长度不会超过 1010 个字母,最多有 250000250000 根木棍。

输出格式

如果木棒能够按要求排列,输出 Possible,否则输出 Impossible

输入输出样例

输入 #1复制
blue red
red violet
cyan blue
blue magenta
magenta cyan
输出 #1复制
Possible

上代码:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<map>
#include<cstring>
using namespace std;
#define xx 1000010
char s1[51],s2[50];
int tot=0,tot_v=1,k,ta=0;
//tot记录点数 ,k记录出度为奇数的点的个数。 
int exist[xx],sum=0;
//这两个用于判断是否只有一个树。 
struct er  
{  
    int hash;  
    int next[27];  
}a[800001];
struct re
{
	int t,next,head,s,out,in;
}e[xx*4];
int search(char s[50])//hash字典树 
{  
    int l = strlen(s);  
    int p = 1; 
    for (int i = 1; i <= l; i++)  
    {  
        int x = s[i - 1] - 'a' + 1;
        if (a[p].next[x] == 0)  
        {  
            tot_v++;  
            a[p].next[x] = tot_v;  
        }  
        p = a[p].next[x];  
    }  
    if (a[p].hash == 0)
        a[p].hash = ++tot;  
    return a[p].hash;  
}  
void build(int x,int y)//建树 
 {
 	e[++ta].t=y;e[ta].s=x;
 	e[x].out++;e[y].in++;
	e[ta].next=e[x].head;e[x].head=ta;
 }
 void dfs(int x)//遍历判断是否是一个树或森林。 
 {
 	for(int i=e[x].head;i;i=e[i].next)
 	{
 		if(exist[e[i].t]==0)
 		{
 			exist[e[i].t]=1;
 			++sum;//记录一个树中的点数,看是否等于tot。 
 			dfs(e[i].t);
 		}
 	}
 }
int main()
{
	while(cin>>s1>>s2)
	{
		int x,y;
		x=search(s1);//变字符为数字,方便记录。 
		y=search(s2);
		build(x,y);build(y,x);
	}
	for(int i=1;i<=tot;++i)
	{
		if(e[i].out%2!=0)
		++k;
	}
	dfs(1);
	int u=0;
	if(sum==tot)
	u=0;
	else u=1;
	if(u==1)//如果是森林,则不联通。 
	{
		cout<<"Impossible";
		return 0;
	}
	if((k==2||k==0))
	cout<<"Possible";
	if(k!=2&&k!=0)
	cout<<"Impossible";
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值