Uva(10129)+Uva(10054)

来源:互联网 发布:iphone桌面软件管理 编辑:程序博客网 时间:2024/06/07 16:50
这两道题都是和欧拉图的判定有关,一个是有向图,一个是无向图的欧拉图的判定还有一个是有向图= =

先看10129。。。我们把单词的首字母看做是入度,最后一个字符看做是初度,那么这道题就变成图中是否存在欧拉回路。判断有向图的条件是该图是连通图和最多最有两个点的出度不等于入度,其实那两个点就是起点和终点,而且必须是其中一个点的入度比出度恰好大1(作为终点),另一个点的出度比它的入度恰好大1(作为起点)

连通图的话我们用并查集来判断,如果该图是连通图的话,那么他们共用祖先= =

#include<stdio.h>#include<string.h>#include<iostream>#include<algorithm>using namespace std;int p[30];const int maxn=100000;int a[30],b[30];char s[1000];void init(){    for(int i=0;i<26;i++)    p[i]=i;}int find(int x){    return p[x]==x?x:find(p[x]); }int main(){    int t,n;    scanf("%d",&t);    while(t--)    {        init();        memset(a,0,sizeof(a));        memset(b,0,sizeof(b));        scanf("%d",&n);        for(int i=0;i<n;i++)        {            scanf("%s",s);            int in=s[0]-'a';            int out=s[strlen(s)-1]-'a';             a[in]++;            b[out]++;            if(find(in)!=find(out))             p[find(in)]=find(out);        }        int i,j;        int flag=1;        for( i=0;!a[i]&&!b[i];i++);        for(j=i+1;j<26;j++)        {            if((a[j]||b[j])&&find(i)!=find(j))            {                flag=0;                break;            }         }        int count=0;        if(flag)        {        //    printf("PPPP\n");        for(i=0;!a[i]&&!b[i];i++);        for(j=i+1;j<26;j++)        {           if(a[j]>b[j])           {                if(a[j]-b[j]>1)                {                    flag=0;                    break;                }                else                count++;            }           else if(b[j]>a[j])           {              if(b[j]-a[j]>1)                {                    flag=0;                    break;                }                else                count++;           }         }}        if(!flag||count>2)        printf("The door cannot be opened.\n");        else        printf("Ordering is possible.\n");    }    return 0;}                      


10054这道题就是给出无向图然后让你判断是存在欧拉回路= =,如果存在,打印其中任一条欧拉回路,无向图的欧拉回路的判断是该图是连通图和图中不存在奇度顶点

打印的话从任一起点出发,递归输出路径= =

#include<stdio.h>#include<string.h>#include<iostream>#include<algorithm>#include<stack>#include<queue>#include<vector>using namespace std;const int maxn=60;int mp[maxn][maxn];int p[60];int dir[60];int f[maxn];int n;struct node{    int u,v;};void init(){    for(int i=1;i<=50;i++)    p[i]=i;}int find(int x){    return p[x]==x?x:find(p[x]);}void dfs(int u){    int v;    for(v=1;v<=50;v++)    {        if(mp[u][v]>0)        {            mp[u][v]--;                mp[v][u]--;            dfs(v);            printf("%d %d\n",v,u);//若是有向图的话,先把顶点放进栈内,然后从栈顶开始输出路径        }     }}int main(){    int t,tt;     int k=0;     scanf("%d",&t);                   for(tt=0;tt<t;tt++)        {           if(tt)        printf("\n");        memset(dir,0,sizeof(dir));        memset(mp,0,sizeof(mp));            init();        scanf("%d",&n);         int a,b;        for(int i=0;i<n;i++)        {           scanf("%d %d",&a,&b);           mp[a][b]++;            mp[b][a]++;           dir[a]++,dir[b]++;           if(find(a)!=find(b))           p[find(a)]=find(b);        }        printf("Case #%d\n",++k);        int num=0;        int i,j;        int flag=1;        for(i=1;!dir[i];i++);         for( j=i+1;j<=50;j++)        {            if(dir[j]&&find(j)!=find(i))            {                flag=0;                break;            }        }         if(flag)        {            int count=0;            for(j=i+1;j<=50;j++)            if(dir[j]&1)            {                flag=0;                break;            }        }         if(!flag)        {         printf("some beads may be lost\n");        continue;       }        int u;         for(u=0;!dir[u];u++);        dfs(u);    }    return 0;}                    

 

0 0
原创粉丝点击