图论 欧拉路代码模版

来源:互联网 发布: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;}

原创粉丝点击