判欧拉回路或求一个图中欧拉图的个数

判欧拉图两个条件首先联通,其次度全部为欧度。那么就很easy了。
题目:hdoj1878

求一个图中欧拉图的个数。
首先通过连通性求出各个子图,然后求子图中奇数度的个数cnt,cnt/2为欧拉图的个数。若子图没有奇数度,则为一个欧拉回路。
题目:hdoj3018Ant Trip
注意这个题目中可能出现孤立点,不算入欧拉图中。

AC代码:

#include <cstdio>
#include <vector>
#include <iostream>
#include <stack>
#include <cstdio>
#include <string>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
#include <vector>
using namespace std;
const int inf = 0x3f3f3f3f;
const int N = 100030;
int cnt[N];
int ans,cou;
vector<int> g[N];
bool ok[N];
void dfs(int x)
{
    for(int i=0;i<g[x].size();i++)
    {
        int to = g[x][i];
        if(ok[to]==false)
        {
            ok[to] = true;
            cou+=cnt[to]%2;
            dfs(to);
        }
    }
}
void solve(int n)
{
    for(int i=1;i<=n;i++){  //欧拉道路
        if(ok[i]==false)
        {
            if(g[i].size()==0)
            {
                ok[i] = true;
                continue;
            }
            cou = cnt[i]%2;
            ok[i] = true;
            dfs(i);
            if(cou==0)
                ans++; //回路
            else
                ans+=cou/2;
        }
    }
}

int main()
{
    int n,m;
    while(~scanf("%d",&n) && n)
    {
        memset(cnt,0,sizeof(cnt));
        scanf("%d",&m);
        for(int i=0;i<m;i++)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            g[x].push_back(y);
            g[y].push_back(x);
            cnt[x]++;
            cnt[y]++;
        }
        memset(ok,false,sizeof(ok));
        ans = 0;
        solve(n);
        printf("%d\n",ans);
        for(int i=0;i<=n;i++)
            g[i].clear();
    }
    return 0;
}

你可能感兴趣的:(DFS,欧拉回路,欧拉图,判欧拉图,联通块)