Problem Description
Soda has a bipartite graph with n vertices and m undirected edges. Now he wants to make the graph become a complete bipartite graph with most edges by adding some extra edges. Soda needs you to tell him the maximum number of edges he can add.

Note: There must be at most one edge between any pair of vertices both in the new graph and old graph.

 
Input
There are multiple test cases. The first line of input contains an integer T (1≤T≤100), indicating the number of test cases. For each test case:

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.

 
Output
For each test case, output the maximum number of edges Soda can add.
 
Sample Input
2
4 2
1 2
2 3
4 4
1 2
1 4
2 3
3 4
 
Sample Output
2
0
 
Source

 题意:给定一个二分图,要求添加最多的边将原来的二分图变成完全二分图。

解法一: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染色 或者 并查集)的更多相关文章

  1. HDU 5313 Bipartite Graph(二分图染色+01背包水过)

    Problem Description Soda has a bipartite graph with n vertices and m undirected edges. Now he wants ...

  2. HDU 5313——Bipartite Graph——————【二分图+dp+bitset优化】

    Bipartite Graph Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)T ...

  3. HDU 5313 Bipartite Graph

    题意:给一个二分图,问想让二分图变成完全二分图最多能加多少条边. 解法:图染色+dp+bitset优化.设最终的完全二分图两部分点集为A和B,A中点个数为x,B中点个数为y,边数则为x × y,答案即 ...

  4. HDU 5313 Bipartite Graph (二分图着色,dp)

    题意: Soda有一个n个点m条边的二分图, 他想要通过加边使得这张图变成一个边数最多的完全二分图. 于是他想要知道他最多能够新加多少条边. 注意重边是不允许的. 思路: 先将二分图着色,将每个连通分 ...

  5. BZOJ_2303_[Apio2011]方格染色 _并查集

    BZOJ_2303_[Apio2011]方格染色 _并查集 Description Sam和他的妹妹Sara有一个包含n × m个方格的 表格.她们想要将其的每个方格都染成红色或蓝色. 出于个人喜好, ...

  6. P1141 01迷宫 DFS (用并查集优化)

    题目描述 有一个仅由数字00与11组成的n \times nn×n格迷宫.若你位于一格0上,那么你可以移动到相邻44格中的某一格11上,同样若你位于一格1上,那么你可以移动到相邻44格中的某一格00上 ...

  7. hdu 4751 Divide Groups(dfs染色 或 2-sat)

    Problem Description   This year is the 60th anniversary of NJUST, and to make the celebration more c ...

  8. 2015多校第6场 HDU 5354 Bipartite Graph CDQ,并查集

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5354 题意:求删去每个点后图是否存在奇环(n,m<=1e5) 解法:很经典的套路,和这题一样:h ...

  9. HDU 5285 wyh2000 and pupil(dfs或种类并查集)

    wyh2000 and pupil Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Other ...

随机推荐

  1. FilterDispatcher已被标注为过时解决办法

    一些struts2的教程都是比较早的,当我们基于较新版本的struts2来实现代码的时候,往往会出现一些问题.比如这个警告:FilterDispatcher isdeprecated! 在web.xm ...

  2. hadoop权威指南 chapter2 MapReduce

    MapReduce MapReduce is a programming model for data processing. The model is simple, yet not too sim ...

  3. 基于bootstrap的datatable控件

    https://editor.datatables.net/release/DataTables/extras/Editor/examples/bootstrap.htmlhttps://github ...

  4. mysql Encryption and Compression Functions

    Name Description AES_DECRYPT() Decrypt using AES AES_ENCRYPT() Encrypt using AES COMPRESS() Return r ...

  5. 如何用Github的gh-pages分支展示自己的项目

    很多新同学觉得github不就是一个代码托管所吗,如何能展示项目呢?其实完全可以借助Github的gh-pages打造出自己的一个作品集,无论是对自己的提升整合还是日后的面试都大有裨益. 前置准备 G ...

  6. JavaScript异步编程 ( 一 )

    1. 异步编程 Javascript语言的执行环境是"单线程"(single thread).所谓"单线程",就是指一次只能完成一件任务.如果有多个任务,就必须 ...

  7. 浏览器格式化JSON输出,thinkphp

    1 //编写类方法用$this->ajaxReturn()返回数据 2 public function index(){ 3 $user = M('User'); 5 $data = $user ...

  8. jQuery animate easing使用方法

    从jQuery API 文档中可以知道,jQuery自定义动画的函数.animate( properties [, duration] [, easing] [, complete] )有四个参数: ...

  9. Image控件的简单使用示例1

    Image控件加载图片包括加载动态图片,加载静态图片两种方式.一.加载动态图片通过生成一个BitmapImage,创建该对象后,赋给Image的Source即可.加载的形式: 示例1 BitmapIm ...

  10. Create new Android Virtual Device时不能创建

    在Create new Android Virtual Device时不能创建... 因为之前有重装过系统,ADT和java都没有更换,不知道是不是有哪里的环境(C盘中的配置)出错了... LOG在下 ...