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 ...
随机推荐
- Linux驱动开发常用头文件
头文件目录中总共有32个.h头文件.其中主目录下有13个,asm子目录中有4个,linux子目录中有10个,sys子目录中有5个.这些头文件各自的功能如下: 1.主目录 <a.out.h> ...
- IntelliJ IDEA 的Project structure说明
IntelliJ IDEA 的Project structure可以在File->Project structure中打开,同时,在新建项目是IDE一般用向导的方式让你填写Project str ...
- Java多线程练习二
public class ex3 { public static void main(String [] args) { thread2 t1 = new thread2("hello&qu ...
- sql 字段字符串内容替换
SELECT * FROM dbo.Table WHERE Name LIKE '%NYCL23%'UPDATE Table SET Name=replace(Name,'NYCL23','WYCL1 ...
- 贴近浏览器窗口右侧的jqueryui dialog快速从左侧调整大小时对话框大小设置不准确的问题
之前在做两个相同的页面的事件同步时发现了这个问题,现在把它记录下来. 一.问题描述 页面中的jqueryui对话框,如果把它拖动到靠近浏览器窗口右侧边缘,并快速从对话框左侧调整对话框窗口大小时,对话框 ...
- 3月25日 javascript练习
1.找出100以内带7的数字 2.求1!+2!+3!+......+n!的和
- 使用redis缓存加索引处理数据库百万级并发
使用redis缓存加索引处理数据库百万级并发 前言:事先说明:在实际应用中这种做法设计需要各位读者自己设计,本文只提供一种思想.准备工作:安装后本地数redis服务器,使用mysql数据库,事先插入1 ...
- sql语句读取所有父子标签
select A.HOSPITAL_ID from T_HOSPITAL A connect by prior A.HOSPITAL_ID=A.PARENT_ID start with A.HOSPI ...
- [转]IBInspectable / IBDesignable
原文:http://www.cocoachina.com/ios/20150227/11202.html 无论陈词滥调多少次,比起一个需要我们记住并且输入什么的界面来说,如果替换成我们能够看见并可控制 ...
- [每日一题JS] 正则表达式
判断字符串是否是这样组成的,第一个必须是字母,后面可以是字母.数字.下划线,总长度为5-20 var reg = /\b[a-zA-Z]{1}[a-zA-Z0-9_]{4,19}\b/; var fl ...