• 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;
    }
  • 相关阅读:
    Vue之利用vueRouter的元信息实现页面的缓存
    Vue之directives所遇小bug
    《CSS世界》读书笔记
    git 错误error: failed to push some refs to
    v-text指令消除刷新慢显示替换的过程
    防抖案例实战之仿百度搜索框即时搜索
    数字金额转大写金额
    常见前端安全
    sendmail邮箱部署设置
    Shell之监控cpu、内存、磁盘脚本
  • 原文地址:https://www.cnblogs.com/tallisHe/p/4671818.html
Copyright © 2020-2023  润新知