问题描述
  1. Soda有一个$n$个点$m$条边的二分图, 他想要通过加边使得这张图变成一个边数最多的完全二分图. 于是他想要知道他最多能够新加多少条边. 注意重边是不允许的.
输入描述
  1. 输入有多组数据. 第一行有一个整数$T$ $(1 \le T \le 100)$, 表示测试数据组数. 然后对于每组数据:
  2.  
  3. 第一行报包含两个整数$n$$m$, $(2 \le n \le 10000, 0 \le m \le 100000)$.
  4.  
  5. 接下来$m$行, 每行两个整数$u$$v$$ (1 \le u, v \le n, v \ne u)$, 表示$u$$v$之间有一条无向边.
  6.  
  7. 输入保证给出的图是二分图, 没有重边, 没有自环. 大部分数据都是小数据.
输出描述
  1. 对于每组数据, 输出Soda最多能加的边数.
输入样例
  1. 2
  2. 4 2
  3. 1 2
  4. 2 3
  5. 4 4
  6. 1 2
  7. 1 4
  8. 2 3
  9. 3 4
输出样例
  1. 2
  2. 0
  3.  
  4.   题目分析:题目我截取的是汉语页面,给你提个二分图,当然测试数据会保证它一定是一个二分图。现在想要给它加边变成一个边数最多完全二
    分图。
    完全二分图的样子如下:

  1.   我们简单的假设:上边的点属于A集合,下面的点属于B集合。A集合中的每一个点都要与B集合中每一个点有边连接,并且集合内部之间的点是
    没有边连接的,这样的图才是完全二分图。完全二分图的边数=A集合的点数*B集合的点数。
  2.  
  3.   我们该如何解这个问题呢?
    思路:因为测试数据会保证给出的图一定是一个二分图,我们可以通过一次bfs搜索,将图中的节点分成AB两个集
    合。此处需要注意的是并不一定所有的点都在图当中,也就是说有的节点可能是孤立的。我们需要把剩下的那些孤立的节点再分配到AB集合当中去。
    徐泽分配到那个集合需要一定的思考。此处先说明一个样例问题:给你一条一定长的线段,让它围成的矩形面积最大,怎么搞?当然是尽量的让它的
    长和宽尽量相等接近正方形时最大啊! 同理,如果我们要让这些节点组成一个最大的完全二分图,那就是尽量让两个集合的节点尽量一样多。通过
    一次bfs搜索后就可以确定AB节点的数量了,这是确定的,不能更改。我们只能通过剩下的那些孤立的节点(孤立的节点数目可能为0)来让AB
    两个集合点数尽量相同。至于怎么分配这剩下的孤立的节点数就不用细说了吧!
  4.  
  5. code:
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include <math.h>
  5. #include <ctype.h>
  6. #include <iostream>
  7. #include <queue>
  8. #include <stack>
  9. #include <vector>
  10. #include <algorithm>
  11. #define PI acos(-1.0);
  12. #define N 10000+10
  13. #define M 100000+10
  14.  
  15. using namespace std;
  16.  
  17. int n, m;
  18. vector<int>q[N];
  19. int flag[N];
  20. bool vis[N];
  21.  
  22. void bfs(int dd)
  23. {
  24. //0代表未着色,1代表白色,2代表黑色
  25.  
  26. queue<int>p;
  27. while(!p.empty()) p.pop();
  28. p.push(dd);
  29. flag[dd]=1;
  30. vis[dd]=true;
  31. while(!p.empty())
  32. {
  33. int dd=p.front(); p.pop();
  34.  
  35. for(int i=0; i<q[dd].size(); i++)
  36. {
  37. if(flag[q[dd][i]]==0 && vis[q[dd][i]]==false )
  38. {
  39. flag[q[dd][i]] = flag[dd]==1?2:1;
  40. p.push(q[dd][i]);
  41. }
  42. }
  43. }
  44.  
  45. }
  46.  
  47. int main()
  48. {
  49. int tg;
  50. scanf("%d", &tg);
  51.  
  52. int n;
  53. int i, j, k;
  54.  
  55. while(tg--){
  56. scanf("%d %d", &n, &m);
  57. int u, v;
  58.  
  59. for(i=1; i<=n; i++)
  60. q[i].clear();
  61. for(i=0; i<m; i++)
  62. {
  63. scanf("%d %d", &u, &v);
  64. q[u].push_back(v);
  65. q[v].push_back(u); //建立无向图
  66. }
  67. memset(flag, 0, sizeof(flag));
  68. memset(vis, false, sizeof(vis));
  69.  
  70. bfs(1);
  71. int cnt1=0, cnt2=0;
  72.  
  73. for(i=1; i<=n; i++)
  74. if(flag[i]==1 ) cnt1++;
  75. for(i=1; i<=n; i++)
  76. if(flag[i]==2) cnt2++;
  77.  
  78. int aa=n-cnt1-cnt2; //aa是孤立节点数
  79. int bb=max(cnt1, cnt2)-min(cnt1, cnt2); //bb是两个集合的节点数之差
  80.  
  81. if( aa <= bb ){
  82. int cc=min(cnt1, cnt2); cc=cc+aa;
  83. if(cnt1<=cnt2) cnt1=cc;
  84. else cnt2=cc;
  85. }
  86. else{
  87. int cc=min(cnt1, cnt2); cc=cc+bb;
  88. aa=aa-bb;
  89. if(cnt1<=cnt2) cnt1=cc;
  90. else cnt2=cc;
  91.  
  92. cnt1=cnt1+aa/2;
  93. aa=aa-aa/2;
  94. cnt2=cnt2+aa;
  95. }
  96. printf("%d\n", cnt1*cnt2-m);
  97. }
  98. return 0;
  99. }
  1.  

BestCoder 1st Anniversary 1004 Bipartite Graph 【二分图 + bfs + 良好的逻辑思维 】的更多相关文章

  1. 二分图点染色 BestCoder 1st Anniversary($) 1004 Bipartite Graph

    题目传送门 /* 二分图点染色:这题就是将点分成两个集合就可以了,点染色用dfs做, 剩下的点放到点少的集合里去 官方解答:首先二分图可以分成两类点X和Y, 完全二分图的边数就是|X|*|Y|.我们的 ...

  2. BestCoder 1st Anniversary($) 1003 Sequence

    题目传送门 /* 官方题解: 这个题看上去是一个贪心, 但是这个贪心显然是错的. 事实上这道题目很简单, 先判断1个是否可以, 然后判断2个是否可以. 之后找到最小的k(k>2), 使得(m-k ...

  3. hdu 5311 Hidden String (BestCoder 1st Anniversary ($))(深搜)

    http://acm.hdu.edu.cn/showproblem.php?pid=5311 Hidden String Time Limit: 2000/1000 MS (Java/Others)  ...

  4. BestCoder 1st Anniversary ——HDU5312(数学推导)

    Today, Soda has learned a sequence whose n-th (n≥1) item is 3n(n−1)+1. Now he wants to know if an in ...

  5. BestCoder 1st Anniversary

    Souvenir  Accepts: 1078  Submissions: 2366  Time Limit: 2000/1000 MS (Java/Others)  Memory Limit: 26 ...

  6. BestCoder 1st Anniversary B.Hidden String DFS

    B. Hidden String Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://bestcoder.hdu.edu.cn/contests/co ...

  7. BestCoder 1st Anniversary ($) 1002.Hidden String

    Hidden String Accepts: 437 Submissions: 2174 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 26 ...

  8. 【BestCoder 1st Anniversary】

    AB题都是签到题.... C 题意: 有一串数列,An=3*n*(n-1)+1 然后要从A数列中选取尽量少个数(可重复),使得Sum(An)=m 题解: 贪心地想,能拿大就拿大很明显就是错的...[哪 ...

  9. hdu 5310 Souvenir(BestCoder 1st Anniversary ($))

    http://acm.hdu.edu.cn/showproblem.php?pid=5310 题目大意:要买n个纪念品,可以单个买p元每个,可以成套买q元一套,每套有m个,求最少花费 #include ...

随机推荐

  1. 阻止YII 1.0自动加载内置JQUERY库

    有些时候我们会在项目中用到很多js库, 因为Yii 1.0框架会默认自动加载一些自带核心库, 很容易引起冲突问题, 下面的代码就展示了如何在Yii 1.0框架下取消jQuery自动加载. Open C ...

  2. LINUX find 实用

    查找文件find ./ -type f 查找目录find ./ -type d 查找名字为test的文件或目录find ./ -name test 查找名字符合正则表达式的文件,注意前面的‘.*’(查 ...

  3. Java基础IO流

    流 流的本质是数据传输,根据数据传输特性将流抽象为各种类,方便更直观的进行数据操作.IO流最终要以对象来体现,对象都存在IO包中. IO流的分类 根据处理数据类型的不同分为:字符流和字节流 根据数据流 ...

  4. js-音乐播放器,播放|暂停|滑块的功能

    音乐播放器,播放|暂停|滑块的功能 document.addEventListener('DOMContentLoaded', function loaded(event) { var audio = ...

  5. Win7 64bit+Anaconda(3-5.0.1,Python3.6)+Pycharm(community-2017.3.3)+OpenCV(python‑3.4.0‑cp36‑cp36m)(转载)

    Anaconda(3-5.0.1,Python3.6)下载链接:https://pan.baidu.com/s/1bqFwLMB 密码:37ih Pycharm(community-2017.3.3) ...

  6. windows下composer安装

    第一步:配置path.这里我的php在C:\… \php目录下面. 第二步: 方法一: 使用安装程序 这是将 Composer 安装在你机器上的最简单的方法. 下载并且运行 Composer-Setu ...

  7. C++ 错误积累

    错误一 VS2012错误:不能在成员函数  的类外部重新声明该函数 解决:检查函数的大括号匹配

  8. SQL SERVER 查看表是否存在

    查看表是否存在 if exists(select 1 from sysobjects where id = OBJECT_ID('数据库名称.dbo.表明称')) drop table 为字段添加注释 ...

  9. POJ1942

    Paths on a Grid Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 24236   Accepted: 6006 ...

  10. intellij idea pycharm phpstorm webstorm 使用 FiraCode 作为编程字体,更新后字符乱码问题解决

    先说使用下载 传送门 https://pan.baidu.com/s/1OI-novVYy-C74HIUfr9E6w windows: 1.下载后打开ttf文件夹,选择所有右键安装. 2.或者使用ch ...