zoukankan      html  css  js  c++  java
  • hdoj 3018 Ant Trip(无向图欧拉路||一笔画+并查集)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3018

    思路分析:题目可以看做一笔画问题,求最少画多少笔可以把所有的边画一次并且只画一次;

    首先可以求出该无向图中连通图的个数,在每个无向连通图中求出需要画的笔数再相加即为所求。在一个无向连通图中,如果所有的点的度数为偶数则存在一个欧拉回路,

    则只需要画一笔即可;如果图中存在度数为奇数的点,则需要画的笔数为度数为奇数的点的个数 /2;需要注意的孤立的点不需要画;

     

    代码如下:

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    using namespace std;
    
    const int MAX_N = 100000 + 100;
    int fa[MAX_N], odd[MAX_N];
    int link[MAX_N], set_count[MAX_N];
    
    void Init()
    {
        for (int i = 0; i < MAX_N; ++i)
        {
            set_count[i] = 1;
            fa[i] = i;
        }
    }
    
    int Find(int num)
    {
        if (fa[num] == num)
            return num;
        else
            return fa[num] = Find(fa[num]);
    }
    
    int Union(int a, int b)
    {
        int fa_a = Find(a);
        int fa_b = Find(b);
    
        if (fa_a == fa_b)
            return -1;
        else if (fa_a > fa_b)
        {
            fa[fa_b] = fa_a;
            set_count[fa_a] += set_count[fa_b];
        }
        else
        {
            fa[fa_a] = fa_b;
            set_count[fa_b] += set_count[fa_a];
        }
        return 1;
    }
    
    int main()
    {
        int vertex_num, road_num;
        int ver_1, ver_2;
    
        while (scanf("%d %d", &vertex_num, &road_num) != EOF)
        {
            int ans = 0;
    
            Init();
            memset(link, 0, sizeof(link));
            memset(odd, 0, sizeof(odd));
            for (int i = 0; i < road_num; ++i)
            {
                scanf("%d %d", &ver_1, &ver_2);
                link[ver_1]++;
                link[ver_2]++;
                Union(ver_1, ver_2);
            }
            for (int i = 1; i <= vertex_num; ++i)
            {
                int fa = Find(i);
                if ((link[i] & 1) == 1)
                    odd[fa]++;
            }
            for (int i = 1; i <= vertex_num; ++i)
            {
                if (fa[i] == i && set_count[i] != 1)
                {
                    if (odd[i] == 0)
                        ans++;
                    else
                        ans += odd[i] / 2;
                }
            }
            printf("%d
    ", ans);
        }
        return 0;
    }
  • 相关阅读:
    使用 VS Code 开发和调试 Burp Suite 扩展
    后渗透神器 Empire 基础用法
    5种语言的按钮事件 断点
    X64下MmIsAddressValid的逆向及内存寻址解析
    x64 内存共享区 KUSER_SHARED_DATA
    内存映射+远线程 调用游戏CALL
    C语言运算符总结
    x32 x64的不同传参方式
    内存占用的一些小问题
    x64分页机制 9
  • 原文地址:https://www.cnblogs.com/tallisHe/p/4671818.html
Copyright © 2011-2022 走看看