码迷,mamicode.com
首页 > 编程语言 > 详细

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

时间:2017-09-02 17:59:15      阅读:136      评论:0      收藏:0      [点我收藏+]

标签:using   ges   欧拉通路   idt   line   http   freopen   es2017   情况   

题目:

技术分享

题解:

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

  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;
  }
}

 

  

 

 

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

标签:using   ges   欧拉通路   idt   line   http   freopen   es2017   情况   

原文地址:http://www.cnblogs.com/AseanA/p/7467180.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!