算法複習——歐拉回路(uoj117)

題目:

題解:

  歐拉回路相關定理(相關定義和證實請參見其餘資料):ios

  1.歐拉回路網絡

    (1)有向圖:全部點的出度都等於入度爲該圖爲歐拉圖(存在歐拉回路)的充要條件。優化

    (2)無向圖:全部點的度都爲偶數爲該圖爲歐拉圖(存在歐拉回路)的充要條件。spa

  2.歐拉通路3d

    (1)有向圖:除兩點(其中一點出度+1==入度,另外一點入度+1==出度)另外點出度都等於入度爲該圖爲半歐拉圖(存在歐拉通路)的充要條件。code

    (2)無向圖:除兩點(兩點度都爲奇數)另外點的度都爲偶數爲該圖爲半歐拉圖(存在歐拉通路)的充要條件。blog

  以上定理用於判斷是否爲存在歐拉回路或者通路string

  接下來是兩個推論:it

  

 

  

  嗯就是這樣··再回到這道題上,一道很裸地模版題···然而被uoj大佬的數據教作人··io

  注意斷定重邊否則就會超時·····用相似於網絡流的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;
  }
}
相關文章
相關標籤/搜索