hdu 5313 Bipartite Graph(dfs染色 或者 并查集)
Note: There must be at most one edge between any pair of vertices both in the new graph and old graph.
The first line contains two integers n and m, (2≤n≤10000,0≤m≤100000).
Each of the next m lines contains two integer u,v (1≤u,v≤n,v≠u) which means there's an undirected edge between vertex u and vertex v.
There's at most one edge between any pair of vertices. Most test cases are small.
4 2
1 2
2 3
4 4
1 2
1 4
2 3
3 4
0
题意:给定一个二分图,要求添加最多的边将原来的二分图变成完全二分图。
解法一:dfs染色:
ans[0]表示左边的图的点个数, ans[1]表示右边的点个数,跑一个dfs,将给定二分图分成两种颜色(color数组用来记录是否染色到),然后没有染色到的就加入左右两边,使得左右两边尽可能接近,相乘 再减掉原来给定边的数量就是能加得最多的边数了。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<set>
#include<map>
using namespace std;
#define N 10006
int n,m;
vector<int>G[N];
int color[N];
int ans[];
void init()
{
for(int i=;i<=n;i++)
{
G[i].clear();
color[i]=-;
}
ans[]=ans[]=; }
void dfs(int cur,int cnt)
{
for(int i=;i<G[cur].size();i++)
{
int u=G[cur][i];
if(color[u]==-)
{
color[u]=;
ans[cnt]++;
dfs(u,cnt^);
}
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
init();
for(int i=;i<m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
G[x].push_back(y);
G[y].push_back(x);
}
for(int i=;i<=n;i++)
{
if(color[i]==- && G[i].size()!=)
{
color[i]=;
ans[]++;
dfs(i,);
}
} int res=; for(int i=;i<=n;i++)
{
if(color[i]==-)
res++;
} while(res--)
{
if(ans[]<ans[])
ans[]++;
else
ans[]++;
}
printf("%d\n",ans[]*ans[]-m);
} return ;
}
解法二:并查集
dis数组用来记录各个点的状态,即记录点是加入左边还是右边。其他的基本相同。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define N 10006
int n,m;
int vis[N];
int fa[N];
int dis[N];
void init()
{
for(int i=;i<=n;i++)
{
fa[i]=i;
vis[i]=dis[i]=;
}
}
int find(int x)
{
if(x!=fa[x])
{
int t=find(fa[x]);
dis[x]=(dis[x]+dis[fa[x]])&;
fa[x]=t;
}
return fa[x];
}
void merge(int x,int y)
{
int root1=find(x);
int root2=find(y);
if(root1==root2) return;
fa[root1]=root2;
dis[root1]=(dis[x]+dis[y]+)&;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
init();
for(int i=;i<m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
merge(x,y);
vis[x]=vis[y]=;
} //int cnt=x=y=0;
int cnt=;
int x=;
int y=;
for(int i=;i<=n;i++)
find(i);
for(int i=;i<=n;i++)
{
if(vis[i]) if(dis[i]&) x++; else y++;
else cnt++;
}
while(cnt--)
{
if(x<y)
x++;
else
y++;
}
printf("%d\n",x*y-m); }
return ;
}
hdu 5313 Bipartite Graph(dfs染色 或者 并查集)的更多相关文章
- HDU 5313 Bipartite Graph(二分图染色+01背包水过)
Problem Description Soda has a bipartite graph with n vertices and m undirected edges. Now he wants ...
- HDU 5313——Bipartite Graph——————【二分图+dp+bitset优化】
Bipartite Graph Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)T ...
- HDU 5313 Bipartite Graph
题意:给一个二分图,问想让二分图变成完全二分图最多能加多少条边. 解法:图染色+dp+bitset优化.设最终的完全二分图两部分点集为A和B,A中点个数为x,B中点个数为y,边数则为x × y,答案即 ...
- HDU 5313 Bipartite Graph (二分图着色,dp)
题意: Soda有一个n个点m条边的二分图, 他想要通过加边使得这张图变成一个边数最多的完全二分图. 于是他想要知道他最多能够新加多少条边. 注意重边是不允许的. 思路: 先将二分图着色,将每个连通分 ...
- BZOJ_2303_[Apio2011]方格染色 _并查集
BZOJ_2303_[Apio2011]方格染色 _并查集 Description Sam和他的妹妹Sara有一个包含n × m个方格的 表格.她们想要将其的每个方格都染成红色或蓝色. 出于个人喜好, ...
- P1141 01迷宫 DFS (用并查集优化)
题目描述 有一个仅由数字00与11组成的n \times nn×n格迷宫.若你位于一格0上,那么你可以移动到相邻44格中的某一格11上,同样若你位于一格1上,那么你可以移动到相邻44格中的某一格00上 ...
- hdu 4751 Divide Groups(dfs染色 或 2-sat)
Problem Description This year is the 60th anniversary of NJUST, and to make the celebration more c ...
- 2015多校第6场 HDU 5354 Bipartite Graph CDQ,并查集
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5354 题意:求删去每个点后图是否存在奇环(n,m<=1e5) 解法:很经典的套路,和这题一样:h ...
- HDU 5285 wyh2000 and pupil(dfs或种类并查集)
wyh2000 and pupil Time Limit: 3000/1500 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Other ...
随机推荐
- MVC框架个人浅析
1.概述: 相信不少前端从业者,都会遇到MVC编程模式,现今多数轻量级网站用php作为后台交互,MVC编程模式用于JAVAWEB开发,应用类型以系统占多数(包括并不限于系统,电商网站,平台交互当然都能 ...
- POJ 3254 Corn Fields (状态压缩DP)
题意:在由方格组成的矩形里面种草,相邻方格不能都种草,有障碍的地方不能种草,问有多少种种草方案(不种也算一种方案). 分析:方格边长范围只有12,用状态压缩dp好解决. 预处理:每一行的障碍用一个状态 ...
- XCode 打包问题巧遇
XCode 打包问题巧遇 太阳火神的漂亮人生 (http://blog.csdn.net/opengl_es) 本文遵循"署名-非商业用途-保持一致"创作公用协议 转载请保留此句: ...
- 对return 语句的正确性和效率进行检查
注意事项如下: 1. return 语句不可返回指向"堆栈内存“的”指针“或者”引用“,因为该内存单元在函数体结束时被自动释放. //错误 char* Func(void) { char s ...
- mvc自带的异步表单提交
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.We ...
- (转)js学习笔记()函数
1.调用函数时,如果参数多于定义时的个数,则多余的参数将会被忽略,如果少于定义时的个数则缺失的参数数会被自动赋予undefined值. 2.如果是用function语句声明的函数定义则不可以出现在循环 ...
- channel c3 disabled, job failed on it will be run on another channel
今天执行备份时,报错: allocated channel: c3 channel c3: sid=131 instance=orcl2 devtype=DISK RMAN-03009: fail ...
- 使用angularjs中ng-repeat的$even与$odd属性时的注意事项
JavaScript中数组的索引是从0开始的,因此我们再取奇偶的时候需要用!$even和!$odd来将$even和$odd的布尔值反转 下面给出一个实例: 使用$odd和$even来制作一个红蓝相间的 ...
- Jquery简略API使用
都是个人随手笔记,既然开通了博客园就分享给大家.谨做为参考,具体大家自己测试以及使用 ★ $() ★ JQ的一个万能获取对象的函数(获取跟CSS获取元素是一样的)$(function(){}); 替代 ...
- jQuery 幻灯片 ----摘录
Cloud Carousel (演示 | 下载) ShineTime (演示 | 下载) Nivo Slider (演示 | 下载) Interactive Photo Desk (演示 | 下载) ...