• Bipartite Graph hdu 5313 bitset 并查集 二分图


    题目:http://acm.hdu.edu.cn/showproblem.php?pid=5313

    题意:

    给出n个顶点,m条边,问最多添加多少条边使之构成一个完全二分图

    存储结构:

    bitset     【用法详情:http://blog.csdn.net/piaocoder/article/details/47177891】

    用时:624ms

    思路:

    二分图的总边数即:n*m(假设一个有n个点,另一个有m个点)

    题目是给出总共的点数为n,间接求最大的边数

    想到一个小学题:给出长度为n的绳子,将其分为两截,使以这两截长度作为长和宽的矩形面积最大,当然,就是平分喽

    虽然,此题不一定和小学题一模一样,但是要想使得分出的n和m乘积最大,必须使n和m尽可能相近,没问题吧。

    然后我们用一个并查集先分出各个连通图,再做相应的处理即可,详见注释

    代码如下:    

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<bitset>
     5 using namespace std;
     6 const int v_N = 10010;  //总结点数
     7 bitset<v_N> Bit;      //允许多少条边构成一个集合,比如:允许一个点构成一个集合,那么Bit[1]为真,否则为假
     8 int n, m, group, fa[v_N], color[v_N], part_num[v_N][2];
     9 //fa:父亲; color:染色  part_num:同一个集合(并查集得到)中各个颜色所拥有的结点个数
    10 int find(int x)
    11 {
    12     if (x == fa[x])
    13         return x;
    14     int t = fa[x];
    15     fa[x] = find(fa[x]);
    16     color[x] ^= color[t];          //当前与父亲异或,刷新颜色  
    17     return fa[x];
    18 }
    19 void solve()
    20 {
    21     for (int i = 1; i <= n; ++i)
    22         Bit[i] = 0;
    23     Bit[0] = 1;
    24     for (int i = 1; i <= n; ++i)  //统计
    25         part_num[find(i)][color[i]]++;
    26     for (int i = 1; i <= n; ++i)
    27         if (i == fa[i])           //说明一个集合结束了,刷新Bit
    28             Bit = (Bit << part_num[i][0]) | (Bit << part_num[i][1]);
    29     int _max = 0;
    30     for (int i = n / 2 - 1; i <= n / 2 + 1; ++i)  //遍历半数左右即可!!  剪枝
    31         if (Bit[i])
    32             _max = max(_max, i*(n - i) - m);
    33     printf("%d
    ", _max);
    34 }
    35 
    36 int main()
    37 {
    38     scanf("%d", &group);
    39     while (group--)
    40     {
    41         scanf("%d%d", &n, &m);
    42         for (int i = 1; i <= n; ++i)
    43             fa[i] = i, color[i] = part_num[i][0] =  part_num[i][1] = 0;
    44         for (int i = 0; i < m; ++i)
    45         {
    46             int x, y, fx, fy;
    47             scanf("%d%d", &x, &y);
    48             fx = find(x), fy = find(y);
    49             if (fx == fy)
    50                 continue;
    51             fa[fx] = fy; 
    52             color[fx] = 1 ^ color[x] ^ color[y];  //保证同一条边或不同一集合颜色不同,初始为0,所以用1异或
    53         }
    54         solve();
    55     }
    56 }

    感谢您的阅读,生活愉快~

  • 相关阅读:
    ES6 export
    vue-cli3实现分环境打包步骤(给不同的环境配置相对应的打包命令)
    vue.config.js
    npm install 错误 安装 chromedriver 失败的解决办法
    解决JS(Vue)input[type='file'] change事件无法上传相同文件的问题
    CSS设置浏览器滚动条样式
    ELK 性能(3) — 在 Docker 上运行高性能容错的 Elasticsearch 集群
    ELK 性能(2) — 如何在大业务量下保持 Elasticsearch 集群的稳定
    ELK 性能(1) — Logstash 性能及其替代方案
    ElasticSearch 2 (37)
  • 原文地址:https://www.cnblogs.com/lv-anchoret/p/8471713.html
Copyright © 2020-2023  润新知