hud3108--Ant Trip

Ant Trip
根据图中顶点的度数来确定欧拉路和欧拉回路。
题目要求的是有多少笔画能画完,图不一定是完全连通的,可以利用这一点将图进行“分块”。
如果这个分块中所有顶点的度数均为偶数,可以形成一个欧拉回路,则能有一笔画搞定。
然后是寻找欧拉路,一条欧拉路需要一笔,由欧拉路的性质得。在图中的所有奇度数顶点都是欧拉路产生的。
每两个奇度数结点都会产生一条欧拉路。所以算出图中的所有奇度数结点的个数除2就是图中所有欧拉路所产生的笔画数
对于图中可能产生的孤立结点。题目中最后提示说道“没有一条路与某一结点相连接,小蚂蚁就会忘记这个结点”,所以说孤立结点不作考虑。

代码

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int M = 100000+5;
int vis[M], n, father[M], deg[M], m;
int find(int num)
{
    if (num != father[num])
    {
        father[num] = find(father[num]);
    }
    return father[num];
}
void Union(int a, int b)
{
    a = find(a);
    b = find(b);
    if (a != b)
    {
        father[a] = b;
    }
}
int main()
{
#ifndef ONLINE_JUDGE
    freopen("1.txt", "r", stdin);
#endif
    int i, j, a, b, ans, r;
    while(~scanf("%d%d", &n, &m))
    {
        for (i = 0; i <= n; i++)
        {
            father[i] = i;
            vis[i] = 0;
            deg[i] = 0;
        }
        for(i = 0; i < m; i++)
        {
            scanf("%d%d", &a, &b);
            deg[a]++;
            deg[b]++;
            Union(a, b);
        }
        ans = 0;
        for(i = 1; i <= n; i++)
        {
            if (deg[i]%2)
            {
                r = find(i);
                vis[r] = 1;
                ans++;
            }
        } 
        ans /= 2;
        for(i = 1; i <= n; i++)
        {
            if(deg[i] > 0)
            {
                r = find(i);
                if (!vis[r] && i == r)
                {
                    ans ++;
                }
            }
        }
        cout << ans << endl;
    }

    return 0;
}

你可能感兴趣的:(hud3108--Ant Trip)