#include <iostream>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define MAX 510000
#define maxn 27
using namespace std;
int g[MAX];
int indegree[MAX];
int outdegree[MAX];
int set[MAX];
int num=0;
//建立字典树方便查找
struct Trie
{
Trie *next[maxn];
int id;
char data;
};
//查询某个单词是否在字典树中,如果存在,返回id,不存在,返回-1
int IsExist(Trie *root,char *str)
{
int len =strlen(str);
int i;
Trie *p=root;
for(i=0;i<len;i++)
{
int id=str[i]-'a';
if(p->next[id]==NULL)
return -1;
p=p->next[id];
if(i==len-1)
{
return p->id;
}
}
return -1;
}
//把字符串插入字典树root中
void build(Trie *root,char *str)
{
Trie *p=root;
Trie *q;
int len=strlen(str);
for(int i=0;i<len;i++)
{//把每个字符都插入到字典树中
int id=str[i]-'a';
if(p->next[id]!=NULL)
{
p=p->next[id];
continue ;
}
//没有该节点
q=(Trie *)malloc(sizeof(Trie));
q->data=str[i];
for(int j=0;j<maxn;j++)
{
q->next[j]=NULL;
}
if(i==len-1)
{
q->id=num;
}
else
q->id=-1;
p->next[id]=q;
p=p->next[id];
}
num++;
}
void init()
{
memset(g,0,sizeof(g));
memset(indegree,0,sizeof(indegree));
memset(outdegree,0,sizeof(outdegree));
for(int i=0;i<MAX;i++)
{
set[i]=i;
}
}
int findSet(int x)
{
if(x!=set[x])
set[x]=findSet(set[x]);
return set[x];
}
void unionSet(int x,int y)
{
int a=findSet(x);
int b=findSet(y);
if(a==b)
return;
if(set[a]<set[b])
{
set[b]=a;
}
else
{
set[a]=b;
}
}
int main()
{
int i;
Trie *root;
root=(Trie *)malloc(sizeof(Trie));
for(int j=0;j<=maxn;j++)
{
root->next[j]=NULL;
}
init();
//输入
char ch1[12];
char ch2[12];
while(scanf("%s%s",ch1,ch2)!=EOF)
{
int s;
int e;
s=IsExist(root,ch1);
if(s==-1)
{
build(root,ch1);
s=num-1;
}
e=IsExist(root,ch2);
if(e==-1)
{
build(root,ch2);
e=num-1;
}
g[s]=1;
g[e]=1;
//点s和点e的度数自加
indegree[e]++;
outdegree[s]++;
//将点s和e连接起来
unionSet(s,e);
}
int count=0;
int flag=0;
//判断图是否连通——变量一遍所有节点,如果每一个节点的父亲都是相同的,那么图是连通的
for(i=0;i<=num;i++)
{
//如果超过一个点的父亲是他本身,那么表示不连通
if(g[i]==1 && set[i]==i)
{
flag++;
}
}
if(flag>1)//图不连通
{
printf("Impossible\n");
return 0;
}
//如果图连通,判读是否是欧拉路径
/*无向图中,除源点和汇点为奇数除外,其余点的度数都为偶数,或者所有点的度数为偶数,那么存在欧拉路径*/
for(i=0;i<=num;i++)
{
if(g[i]==1)
{
if((indegree[i]+outdegree[i])%2!=0)
{
count++;
}
}
}
if(count==0 || count==2)
printf("Possible\n");
else
printf("Impossible\n");
return 0;
}
图论 欧拉路代码模版
最新推荐文章于 2023-03-05 11:05:50 发布