HDU 3018 Ant Trip(欧拉回路)

题目链接:HDU 3018 Ant Trip

一笔画问题,问需要多少笔才能把边画完,如果一个连通分量是欧拉回路(所有点的度数都是偶数,对于无向图来说),那么这个连通分量可以一笔画完,如果一个连通分量不是欧拉回路,那么需要的笔画数是这个连通分量中奇数度数点的个数除以2。孤立点不连边,显然不考虑。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <set>
#include <iterator>

using namespace std;

const int MAX_N = 100000 + 100;
const int MAX_M = 200000 + 200;
int p[MAX_N], dgr[MAX_M], odd[MAX_N];
int n, m;
set <int> S;

int _find(int x)
{
    return p[x] == x ? x :(p[x] = _find(p[x]));
}

int main()
{
    int u, v, x, y, _par, _size, res;
    while(scanf("%d%d", &n, &m) != EOF)
    {
        res = 0;
        memset(dgr, 0, sizeof(dgr));
        memset(odd, 0, sizeof(odd));
        for(int i = 1; i <= n; i++)
            p[i] = i;
        for(int i = 0; i < m; i++)
        {
            scanf("%d%d", &x, &y);
            u = _find(x), v = _find(y);
            if(u != v)
                p[u] = v;
            dgr[x]++, dgr[y]++;
        }
        for(int i = 1; i <= n; i++)
        {
            if(dgr[i] != 0)
            {
                _par = _find(i);
                if(S.find(_par) == S.end())
                    S.insert(_par);
                if(dgr[i] % 2 == 1)
                    odd[_par]++;
            }
        }
        set <int> :: iterator it = S.begin();
        for(; it != S.end(); it++)
        {
            _par = *it;
            if(odd[_par])
                res += odd[_par] / 2;
            else
                res += 1;
        }
        printf("%d\n", res);
        S.clear();
    }
    return 0;
}


你可能感兴趣的:(HDU 3018 Ant Trip(欧拉回路))