1. 程式人生 > >hdoj 1878 歐拉回路

hdoj 1878 歐拉回路

歐拉回路

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 14279    Accepted Submission(s): 5415


Problem Description 歐拉回路是指不令筆離開紙面,可畫過圖中每條邊僅一次,且可以回到起點的一條迴路。現給定一個圖,問是否存在歐拉回路?
Input 測試輸入包含若干測試用例。每個測試用例的第1行給出兩個正整數,分別是節點數N ( 1 < N < 1000 )和邊數M;隨後的M行對應M條邊,每行給出一對正整數,分別是該條邊直接連通的兩個節點的編號(節點從1到N編號)。當N為0時輸入結
束。
Output 每個測試用例的輸出佔一行,若歐拉回路存在則輸出1,否則輸出0。

Sample Input 3 3 1 2 1 3 2 3 3 2 1 2 2 3 0
Sample Output 1 0
Author ZJU
Source 分析:
尤拉通路判定
        當且僅當G是連通圖且無奇度頂點或有兩個奇度頂點(若有兩個奇度頂點,則它們是每條尤拉通路的端點)。
歐拉回路的判定
        若無奇度頂點 ,則通路為歐拉回路 
        推論=》無向圖G為尤拉圖,當且僅當G是連通的,且無奇度頂點  。
方法一: 1.判斷連通 2.數每個頂點的度數 AC程式碼1【通過深搜判斷連通】:
#include<cstdio>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<string>
#include<stack>
#include<queue>
#include<list>
#include<vector>
#include<map>
#include<algorithm>
using namespace std;
int deg[1005];
int G[1005][1005];
bool vis[1005];
int n,m;

void DFS(int u)
{
    vis[u]=true;
    for(int i=1;i<=n;i++)
        if(G[u][i]&&!vis[i])
        {
         DFS(i);
        }
}
int main()
{
  while(scanf("%d",&n)&&n)
  {
      scanf("%d",&m);
      memset(vis,0,sizeof(vis));
      memset(deg,0,sizeof(deg));
      memset(G,0,sizeof(G));//注意剛開始要清0
      for(int i=1;i<=m;i++)
        {
            int u,v;
            scanf("%d%d",&u,&v);
            G[u][v]=G[v][u]=1;
            deg[u]++;
            deg[v]++;
        }

        DFS(1);//從V1開始深搜

        bool flag=true;
        for(int i=1;i<=n;i++)//根據歐拉回路的判定定理:無奇數度的頂點,連通,則是歐拉回路
        {
            if(deg[i]&1)//若有奇度頂點,直接跳出
            {
              flag=false;
              break;
            }
            if(!vis[i])//判斷是否連通
            {
              flag=false;
              break;
            }
        }
        if(flag)
            printf("1\n");
        else
            printf("0\n");

  }
  return 0;
}
方法二: 判斷連通用並查集判斷即可 AC程式碼2