zoukankan      html  css  js  c++  java
  • 欧拉图

    定义

    欧拉通路
    • 图中行遍所有顶点且恰好经过图中的每条边一次的通路. 顶点可以重复经过,边只经过一次。
    欧拉回路
    • 图中行遍所有顶点且恰好经过图中的每条边一次的回路. 顶点可以重复经过,边只经过一次。
    欧拉图:
    • 有欧拉回路的图
    半欧拉图
    • 有欧拉通路而无欧拉回路的图.

    几点说明:

    1. 上述定义对无向图和有向图都适用.
    2. 规定平凡图为欧拉图.$ $ 平凡图: 1 阶零图,即只有1个顶点没有边的图
    3. 欧拉通路是简单通路, 欧拉回路是简单回路.
    4. 环不影响图的欧拉性.


    图中, ((1), (4))为欧拉图; ((2), (5))为半欧拉图; ((3),(6))既不是欧拉图, 也不是半欧拉图.

    判定

    无向欧拉图
    • 无向图(G)为欧拉图当且仅当(G)连通且无奇度顶点.
    无向半欧拉图
    • 无向图(G)是半欧拉图当且仅当(G)连通且恰有两个奇度顶点.
    有向欧拉图
    • 有向图(D)是欧拉图当且仅当(D)连通且每个顶点的入度都等于出度.
    有向半欧拉图
    • 有向图D具有欧拉通路当且仅当D连通且恰有两个奇度顶点, 其中一个入度出度(1)(终点), 另一个出度入度(1)(起点), 其余顶点的入度等于出度.

    HDU-1878-无向图欧拉回路

    #include<bits/stdc++.h>
    using namespace std;
    const int M=1010;
    int edge[M][M];
    int vis[M];
    int du[M];
    int n,m;
    void init( )
    {
        memset(edge,0,sizeof(edge));
        memset(vis,0,sizeof(vis));
        memset(du,0,sizeof(du));
    }
    void dfs(int x)//判断是否连通
    {
        vis[x]=1;
        for(int i=1;i<=n;i++)
        {
            if(!vis[i]&&edge[x][i])
            {
                dfs(i);
            }
        }
    }
    int cheak(int n)//查找多少个顶点的度是否是奇数
    {
        int ans=0;
        for(int i=1;i<=n;i++)
        {
            if(du[i]%2!=0)
            {
                ans++;
            }
        }
        return ans;
    }
    int main( )
    {
        int x,y;
        while(~scanf("%d%d",&n,&m)&&n)
        {
            init( );
            for(int i=1;i<=m;i++)
            {
                scanf("%d%d",&x,&y);
                edge[x][y]=edge[y][x]=1;
                du[x]++;
                du[y]++;
            }
            dfs(1);
            int flag=1;
            for(int i=1;i<=n;i++)
            {
                if(!vis[i])
                {
                    flag=0;
                    break;
                }
            }
            if(!cheak(n)&&flag)
            {
                printf("1
    ");
            }
            else
            {
                printf("0
    ");
            }
        }
        return 0;
    }
    

    POJ-1386-(有向图)Play on Words

    • 每个单词的第一个字母到最后一个字母有一条有向边,构图
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    int edge[26][26];
    char s[1010];
    // int out[26];
    // int in[26];
    int du[26];
    int vis[26];
    int use[26];
    int n;
    void dfs(int x)
    {
        vis[x]=1;
        for(int i=0; i<26; i++)
        {
            if(edge[x][i]&&!vis[i])
            {
                dfs(i);
            }
        }
    }
    int main( )
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d",&n);
            getchar( );
            // memset(out,0,sizeof(out));
            // memset(in,0,sizeof(in));
            memset(use,0,sizeof(use));
            memset(edge,0,sizeof(edge));
            memset(du,0,sizeof(du));
            while(n--)
            {
                scanf("%s",s);
                getchar( );
                int len=strlen(s);
                int u=s[0]-'a';
                int v=s[len-1]-'a';
                edge[u][v]=1;
                // out[u]++;
                // in[v]++;
                du[u]--;//出度为减
                du[v]++;//入度为加
                use[u]=1;
                use[v]=1;
            }
            int x=-1;
            int flag1=0;
            int flag2=0;
            for(int i=0; i<26; i++)
            {
                if(!use[i])
                {
                    continue;
                }
                else if(du[i]==0)
                {
                    if(x==-1)
                    {
                        x=i;
                    }
                }
                else if(du[i]==-1)
                {
                    flag1++;
                    x=i;
                    if(flag1>1)
                    {
                        break;
                    }
                }
                else if(du[i]==1)
                {
                    flag2++;
                    if(flag2>1)
                    {
                        break;
                    }
    
                }
                else
                {
                    flag1=flag2=-1;
                    break;
                }
                // else if(out[i]==in[i])
                // {
                //     if(x==-1)
                //     {
                //         x=i;
                //     }
    
                // }
                // else if(out[i]-in[i]==1)
                // {
                //     flag1++;
                //     x=i;
                //     if(flag1>1)
                //     {
                //         break;
                //     }
                // }
                // else if(in[i]-out[i]==1)
                // {
                //     flag2++;
                //     if(flag2>1)
                //     {
                //         break;
                //     }
                // }
                // else
                // {
                //     flag1=flag2=-1;
                //     break;
                // }
            }
            if((flag1==1&&flag2==1)||(flag1==0&&flag2==0))//两者为0,欧拉回路,两者为1,欧拉通路
            {
                int flag=0;
                memset(vis,0,sizeof(vis));
                dfs(x);
                for(int i=0; i<26; i++)
                {
                    if(!vis[i]&&use[i])
                    {
                        flag=1;
                        break;
                    }
                }
                if(flag==1)
                {
                    printf("The door cannot be opened.
    ");
                }
                else
                {
                    printf("Ordering is possible.
    ");
                }
    
            }
            else
            {
                printf("The door cannot be opened.
    ");
            }
    
        }
        return 0;
    }
    
  • 相关阅读:
    堆和栈的区别
    .net中类(class)与结构(struct)的不同
    CTS、CLS、CLR
    C#和.Net的关系
    装箱(boxing)和拆箱(unboxing)
    三层架构
    属性和public字段的区别(调用set方法为一个属性设值,然后用get方法读取出来的值一定是set进去的值吗?)
    override与重载(overload)的区别
    C#中的委托是什么?事件是不是一种委托?事件和委托的关系。
    json转树状菜单栏
  • 原文地址:https://www.cnblogs.com/lcbwwy/p/13138395.html
Copyright © 2011-2022 走看看