BestCoder 1st Anniversary 1004 Bipartite Graph 【二分图 + bfs + 良好的逻辑思维 】
Soda有一个$n$个点$m$条边的二分图, 他想要通过加边使得这张图变成一个边数最多的完全二分图. 于是他想要知道他最多能够新加多少条边. 注意重边是不允许的.
输入有多组数据. 第一行有一个整数$T$ $(1 \le T \le 100)$, 表示测试数据组数. 然后对于每组数据: 第一行报包含两个整数$n$和$m$, $(2 \le n \le 10000, 0 \le m \le 100000)$. 接下来$m$行, 每行两个整数$u$和$v$$ (1 \le u, v \le n, v \ne u)$, 表示$u$和$v$之间有一条无向边. 输入保证给出的图是二分图, 没有重边, 没有自环. 大部分数据都是小数据.
对于每组数据, 输出Soda最多能加的边数.
2
4 2
1 2
2 3
4 4
1 2
1 4
2 3
3 4
2
0 题目分析:题目我截取的是汉语页面,给你提个二分图,当然测试数据会保证它一定是一个二分图。现在想要给它加边变成一个边数最多完全二
分图。
完全二分图的样子如下:
我们简单的假设:上边的点属于A集合,下面的点属于B集合。A集合中的每一个点都要与B集合中每一个点有边连接,并且集合内部之间的点是
没有边连接的,这样的图才是完全二分图。完全二分图的边数=A集合的点数*B集合的点数。 我们该如何解这个问题呢?
思路:因为测试数据会保证给出的图一定是一个二分图,我们可以通过一次bfs搜索,将图中的节点分成A、B两个集
合。此处需要注意的是并不一定所有的点都在图当中,也就是说有的节点可能是孤立的。我们需要把剩下的那些孤立的节点再分配到A、B集合当中去。
徐泽分配到那个集合需要一定的思考。此处先说明一个样例问题:给你一条一定长的线段,让它围成的矩形面积最大,怎么搞?当然是尽量的让它的
长和宽尽量相等接近正方形时最大啊! 同理,如果我们要让这些节点组成一个最大的完全二分图,那就是尽量让两个集合的节点尽量一样多。通过
一次bfs搜索后就可以确定A、B节点的数量了,这是确定的,不能更改。我们只能通过剩下的那些孤立的节点(孤立的节点数目可能为0)来让A、B
两个集合点数尽量相同。至于怎么分配这剩下的孤立的节点数就不用细说了吧! code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <ctype.h>
#include <iostream>
#include <queue>
#include <stack>
#include <vector>
#include <algorithm>
#define PI acos(-1.0);
#define N 10000+10
#define M 100000+10 using namespace std; int n, m;
vector<int>q[N];
int flag[N];
bool vis[N]; void bfs(int dd)
{
//0代表未着色,1代表白色,2代表黑色 queue<int>p;
while(!p.empty()) p.pop();
p.push(dd);
flag[dd]=1;
vis[dd]=true;
while(!p.empty())
{
int dd=p.front(); p.pop(); for(int i=0; i<q[dd].size(); i++)
{
if(flag[q[dd][i]]==0 && vis[q[dd][i]]==false )
{
flag[q[dd][i]] = flag[dd]==1?2:1;
p.push(q[dd][i]);
}
}
} } int main()
{
int tg;
scanf("%d", &tg); int n;
int i, j, k; while(tg--){
scanf("%d %d", &n, &m);
int u, v; for(i=1; i<=n; i++)
q[i].clear();
for(i=0; i<m; i++)
{
scanf("%d %d", &u, &v);
q[u].push_back(v);
q[v].push_back(u); //建立无向图
}
memset(flag, 0, sizeof(flag));
memset(vis, false, sizeof(vis)); bfs(1);
int cnt1=0, cnt2=0; for(i=1; i<=n; i++)
if(flag[i]==1 ) cnt1++;
for(i=1; i<=n; i++)
if(flag[i]==2) cnt2++; int aa=n-cnt1-cnt2; //aa是孤立节点数
int bb=max(cnt1, cnt2)-min(cnt1, cnt2); //bb是两个集合的节点数之差 if( aa <= bb ){
int cc=min(cnt1, cnt2); cc=cc+aa;
if(cnt1<=cnt2) cnt1=cc;
else cnt2=cc;
}
else{
int cc=min(cnt1, cnt2); cc=cc+bb;
aa=aa-bb;
if(cnt1<=cnt2) cnt1=cc;
else cnt2=cc; cnt1=cnt1+aa/2;
aa=aa-aa/2;
cnt2=cnt2+aa;
}
printf("%d\n", cnt1*cnt2-m);
}
return 0;
}
BestCoder 1st Anniversary 1004 Bipartite Graph 【二分图 + bfs + 良好的逻辑思维 】的更多相关文章
- 二分图点染色 BestCoder 1st Anniversary($) 1004 Bipartite Graph
题目传送门 /* 二分图点染色:这题就是将点分成两个集合就可以了,点染色用dfs做, 剩下的点放到点少的集合里去 官方解答:首先二分图可以分成两类点X和Y, 完全二分图的边数就是|X|*|Y|.我们的 ...
- BestCoder 1st Anniversary($) 1003 Sequence
题目传送门 /* 官方题解: 这个题看上去是一个贪心, 但是这个贪心显然是错的. 事实上这道题目很简单, 先判断1个是否可以, 然后判断2个是否可以. 之后找到最小的k(k>2), 使得(m-k ...
- 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) ...
- 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 ...
- BestCoder 1st Anniversary
Souvenir Accepts: 1078 Submissions: 2366 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 26 ...
- 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 ...
- BestCoder 1st Anniversary ($) 1002.Hidden String
Hidden String Accepts: 437 Submissions: 2174 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 26 ...
- 【BestCoder 1st Anniversary】
AB题都是签到题.... C 题意: 有一串数列,An=3*n*(n-1)+1 然后要从A数列中选取尽量少个数(可重复),使得Sum(An)=m 题解: 贪心地想,能拿大就拿大很明显就是错的...[哪 ...
- hdu 5310 Souvenir(BestCoder 1st Anniversary ($))
http://acm.hdu.edu.cn/showproblem.php?pid=5310 题目大意:要买n个纪念品,可以单个买p元每个,可以成套买q元一套,每套有m个,求最少花费 #include ...
随机推荐
- nightwatch-js -- test group
Test group 可以将你的测试脚本划分到组中,并根据需要运行它们.要将测试组合在一起,只需将它们放在相同的子文件夹中,文件夹的名字即是组的名字.例如:lib/├── selenium-serve ...
- Online advertising术语
做项目发现非常多Online Advertising术语不懂,看代码感觉不那么清晰,如今来总结下遇到的一些术语. ---------------------------- 1. Online Adve ...
- Swagger跨域访问
我们用springboot开发完后,需要前端vue用swagger跨域,默认是不能跨域的,所以需要我们后台设置跨域访问,将下面代码完整复制即可. 在springboot项目中新建class : Cor ...
- 禁止"Windows Media Player Network Sharing Service"服务自动启动
开始 -> 运行 -> gpedit.msc -> 计算机配置 -> 管理模板 -> Windows 组件 -> Windows Media Player -> ...
- php实现等比例不失真缩放上传图片的方法
本文实例分析了php实现等比例不失真缩放上传图片的方法.分享给大家供大家参考,具体如下: 有时上传图片时因为图片太大了,不仅占用空间,消耗流量,而且影响浏(图片的尺寸大小不一).下面分享一种等比例不失 ...
- zabbix自动化监控三种方式
1.agent自动注册2.sever端自动发现discovery3.zabbix api
- Spring整合JMS(消息中间件)
这一节来说说,异步机制及spring对JMS封装 一.消息异步处理 类似于RMI.Hessian.Burlap等远程方法调用,它们都是同步的,所谓同步调用就是客户端必须等待操作完成,如果远程服务没有返 ...
- Spring Cloud 微服务三: API网关Spring cloud gateway
前言:前面介绍了一款API网关组件zuul,不过发现spring cloud自己开发了一个新网关gateway,貌似要取代zuul,spring官网上也已经没有zuul的组件了(虽然在仓库中可以更新到 ...
- 【问题解决】Tomcat 启动时闪退或提示“Neither the JAVA_HOME or the JRE_HOME environmental variable is defined.”
问题解决思路: 1.分析startup.bat启动脚本:发现其调用了catalina.bat,而catalina.bat调用了setclasspath.bat 2.在setclasspath.bat的 ...
- org.apache.poi3.1.7 Excle并发批量导入导出
org.apache.poi3.1.7 升级,需要修改设置方式: 1.org.apache.poi3.1.4 的设置单元格: XSSFCellStyle cellStyle = wb.createCe ...