• 算法复习——欧拉回路(uoj117)


    题目:

    题解:

      欧拉回路相关定理(相关定义和证明请参见其他资料):

      1.欧拉回路

        (1)有向图:所有点的出度都等于入度为该图为欧拉图(存在欧拉回路)的充要条件。

        (2)无向图:所有点的度都为偶数为该图为欧拉图(存在欧拉回路)的充要条件。

      2.欧拉通路

        (1)有向图:除两点(其中一点出度+1==入度,另一点入度+1==出度)另外点出度都等于入度为该图为半欧拉图(存在欧拉通路)的充要条件。

        (2)无向图:除两点(两点度都为奇数)另外点的度都为偶数为该图为半欧拉图(存在欧拉通路)的充要条件。

      以上定理用于判断是否为存在欧拉回路或者通路

      接下来是两个推论:

      

      

      嗯就是这样··再回到这道题上,一道很裸地模版题···然而被uoj大佬的数据教做人··

      注意判定重边不然就会超时·····用类似于网络流的cur来优化(具体见代码)

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cmath>
    #include<ctime>
    #include<cctype>
    #include<cstring>
    #include<string>
    #include<algorithm>
    using namespace std;
    const int N=1e5+5;
    const int M=5e5+5;
    int first[N],go[M*2],next[M*2],tot=0;
    int n,m,T,ru[N],chu[N],stack[M*2],cnt;
    bool visit[M];
    inline void comb(int a,int b)
    {
      next[++tot]=first[a],first[a]=tot,go[tot]=b;
    }
    inline void dfs1(int u)
    {
      for(int &e=first[u];e;e=next[e])
      {
        if(!visit[e])
        {
          visit[e]=true;
          if(e%2==1)
            visit[e+1]=true;
          else
            visit[e-1]=true;
          int t=e;
          dfs1(go[e]);
          stack[++cnt]=t;
        }
      }
    }
    inline void dfs2(int u)
    {
      for(int &e=first[u];e;e=next[e])
      {
        if(!visit[e])
        {
          visit[e]=true;
          int t=e;
          dfs2(go[e]);
          stack[++cnt]=t;
        }
      }
    }
    int main()
    {
      //freopen("a.in","r",stdin);
      scanf("%d",&T);
      int a,b;
      scanf("%d%d",&n,&m);
      if(T==1)  //无向图情况 
      { 
        for(int i=1;i<=m;i++)
        {
          scanf("%d%d",&a,&b);
          comb(a,b);
          comb(b,a);
          ru[b]++;
          chu[a]++;
        }
        for(int i=1;i<=n;i++)
          if((ru[i]+chu[i])%2==1)
          {
            cout<<"NO"<<endl;
            return 0;
          }
        for(int i=1;i<=n;i++)
        {
          if(first[i])
          {  
            dfs1(i);
            break;
          }
        }
        if(cnt!=m)  
        {  
          cout<<"NO"<<endl;
          return 0;
        }
        cout<<"YES"<<endl;
        for(int i=cnt;i>=1;i--)
        {  
          if(stack[i]%2==1)
            cout<<(stack[i]+1)/2<<" ";
          else
            cout<<stack[i]/2*(-1)<<" ";
        }
        return 0;
      }
      else
      {
        for(int i=1;i<=m;i++)
        {
          scanf("%d%d",&a,&b);
          comb(a,b);
          ru[b]++;
          chu[a]++;
        }
        for(int i=1;i<=n;i++)
          if(ru[i]!=chu[i])
          {
            cout<<"NO"<<endl;
            return 0;
          }
         for(int i=1;i<=n;i++)
         {
           if(first[i])
           {  
             dfs2(i);
             break;
           }
         }
        if(cnt!=m)  
        {  
          cout<<"NO"<<endl;
          return 0;
        }
        cout<<"YES"<<endl;
        for(int i=cnt;i>=1;i--)
          cout<<stack[i]<<" ";
        return 0;
      }
    }

      

     

  • 相关阅读:
    python中的GIL
    centos7 安装docker
    ORACLE INSERT INTO SELECT
    Java substring几个用例
    Java Date类型转换、操作等(util.Date sql.Date,)
    ORACLE 按字段去除重复数据
    OFFICE技巧汇编
    ORACLE自动类型转换的坑
    ubuntu下,pycharm svn 版本控制,svn服务器在win下
    【草稿】pip重要命令;python 变量命名规则
  • 原文地址:https://www.cnblogs.com/AseanA/p/7467180.html
Copyright © 2020-2023  润新知