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 ...
随机推荐
- Dynamics CRM记录页面上隐藏子网格“+”标识
前段时间微软发布了Dynamics 365,这是Dynamics产品的又一次大的变动,期待新的版本能够更好的满足客户的需求,同时提供更多的可定制化的内容. 近期做Dynamics CRM项目遇到很多审 ...
- Linux的VI/VIM
参考自:http://www.cnblogs.com/itech/archive/2009/04/17/1438439.html 作者:iTech 出处:http://itech.cnblogs.co ...
- OD: Heap Exploit : DWORD Shooting & Opcode Injecting
堆块分配时的任意地址写入攻击原理 堆管理系统的三类操作:分配.释放.合并,归根到底都是对堆块链表的修改.如果能伪造链表结点的指针,那么在链表装卸的过程中就有可能获得读写内存的机会.堆溢出利用的精髓就是 ...
- java listener实现定时任务
使用java ServletContextListener 实现各种简单定时任务. 1. 创建ServletContextListener,在3.0版本的web.xml中不再需要添加listener的 ...
- AngularJs练习Demo16 ngRoute
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...
- WdatePicker 设置今天起 后30天可选
<link href="{:ADDON_PUBLIC_PATH}/style/My97DatePicker/skin/WdatePicker.css" rel="s ...
- java比较器Comparator 使用
PresonDemo package cn.stat.p5.person.demo; public class PresonDemo implements Comparable { private S ...
- java 后台线层也叫守护线层
import java.util.concurrent.locks.*; class Do9 { public static void main(String[] args) { Ds d=new D ...
- MFC 点击改变文本 加法计时器 伸缩窗体
1.添加所需控件,设置ID:labNum1,txtNum1.txtNum2.txtNum3.btnAdd,并将labNum1的属性Notify->true(控件在被单击或双击时可以发送消息) 2 ...
- IIS中启用gzip压缩(网站优化)
HTTP协议上的GZIP编码是一种用来改进WEB应用程序性能的技术.大流量的WEB站点常常使用GZIP压缩技术来让用户感受更快的速度.这一般是指WWW服务器中安装的一个功能,当有人来访问这个服务器中的 ...