图论 欧拉路代码模版
来源:互联网 发布:centos共享文件夹在哪 编辑:程序博客网 时间:2024/04/30 17:28
#include <iostream>#include<stdio.h>#include<string.h>#include<stdlib.h>#define MAX 510000#define maxn 27using 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,不存在,返回-1int 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;}elseq->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;}