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
 
Recommend
hujie   |   We have carefully selected several similar problems for you:  

pid=5315" target="_blank" style="color:rgb(26,92,200); text-decoration:none">5315 5314 5312 5311 5310 

 

大致题意:

有n个点。m条边的二分图(可能不连通)。问最多还能加多少条边变成全然二分图

思路:

显然每一连通块,都染成两种颜色,最后要尽量使两种颜色总数同样解才最优

显然有两种决策。不是染白就是染黑,01背包

dp[i][val]表示前i个连通块能染成同一色点数<=val的最大值

显然dp[scc][all/2]是最优解

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <iostream>
#include <cstring>
#include <cmath>
#include <queue>
#include <stack>
#include <list>
#include <map>
#include <set>
#include <sstream>
#include <string>
#include <vector>
#include <cstdio>
#include <ctime>
#include <bitset>
#include <algorithm>
#define SZ(x) ((int)(x).size())
#define ALL(v) (v).begin(), (v).end()
#define foreach(i, v) for (__typeof((v).begin()) i = (v).begin(); i != (v).end(); ++ i)
#define REP(i,n) for ( int i=1; i<=int(n); i++ )
using namespace std;
typedef long long ll;
#define X first
#define Y second
typedef pair<ll,ll> pii; const int N = 10000+100;
const int M = 100000+1000;
struct Edge{
int v,nxt;
Edge(int v = 0,int nxt = 0):v(v),nxt(nxt){}
}es[M*2];
int n,m;
int ecnt;
int head[N];
inline void add_edge(int u,int v){
es[ecnt] = Edge(v,head[u]);
head[u] = ecnt++;
es[ecnt] = Edge(u,head[v]);
head[v] = ecnt++;
}
int col[N];
int cnt[N][2];
int top;
int sum = 0;
void dfs(int u,int fa){
col[u] = !col[fa];
cnt[top][col[u]]++;
for(int i = head[u];~i;i = es[i].nxt){
int v = es[i].v;
if(v == fa || col[v] != -1) continue;
dfs(v,u);
}
}
void ini(){
REP(i,n) head[i] = col[i] = -1,cnt[i][0] = cnt[i][1] = 0;
col[0] = top = sum = ecnt = 0;
}
int dp[2][N];
int main(){ int T;
cin>>T;
while(T--){
scanf("%d%d",&n,&m);
ini();
REP(i,m){
int u,v;
scanf("%d%d",&u,&v);
add_edge(u,v);
}
for(int i = n; i>= 1;i--){
if(col[i] != -1) continue;
top++;
dfs(i,0);
if(cnt[top][0] == 0 || cnt[top][1] == 0) {
cnt[top][0] = cnt[top][1] = 0;
top--;
}
else {
sum += cnt[top][0],sum += cnt[top][1];
}
} int nd = n-sum;
for(int i = 0;i <= sum/2;i++) dp[0][i] = 0;
REP(i,top){
for(int j = 0; j <= sum/2; j++){
dp[i&1][j] = -1;
if(j-cnt[i][0] >= 0 && dp[(i-1)&1][j-cnt[i][0]] != -1) dp[i&1][j] = dp[(i-1)&1][j-cnt[i][0]]+cnt[i][0];
if(j-cnt[i][1] >= 0 && dp[(i-1)&1][j-cnt[i][1]] != -1) {
dp[i&1][j] = max(dp[(i-1)&1][j-cnt[i][1]]+cnt[i][1],dp[i&1][j]);
}
}
int minn,maxx = sum-dp[top&1][sum/2];
int t = min(nd,maxx-dp[top&1][sum/2]);
minn = dp[top&1][sum/2]+t;
nd -= t;
if(nd) minn += nd/2, maxx += nd/2 + (nd&1);
printf("%d\n",minn*maxx-m);
}
}

HDU 5313 Bipartite Graph(二分图染色+01背包水过)的更多相关文章

  1. hdu 5313 Bipartite Graph(dfs染色 或者 并查集)

    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)

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

  4. HDU 5313 Bipartite Graph

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

  5. POJ 1112 Team Them Up! 二分图判定+01背包

    题目链接: http://poj.org/problem?id=1112 Team Them Up! Time Limit: 1000MSMemory Limit: 10000K 问题描述 Your ...

  6. HDU 3639 Bone Collector II(01背包第K优解)

    Bone Collector II Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others ...

  7. HDU 2126 Buy the souvenirs (01背包,输出方案数)

    题意:给出t组数据 每组数据给出n和m,n代表商品个数,m代表你所拥有的钱,然后给出n个商品的价值 问你所能买到的最大件数,和对应的方案数.思路: 如果将物品的价格看做容量,将它的件数1看做价值的话, ...

  8. HDU 1203 I NEED A OFFER! 01背包

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1203 解题思路:简单的01背包,用dp[i]表示花费不超过i时的最大可能性 状态转移方程 dp[i]= ...

  9. HDU 2639 Bone Collector II【01背包 + 第K大价值】

    The title of this problem is familiar,isn't it?yeah,if you had took part in the "Rookie Cup&quo ...

随机推荐

  1. Python 使用cx_freeze 生成exe文件

    在python中比较常用的python转exe方法有三种,分别是cx_freeze,py2exe,PyInstaller.py2exe恐怕是三者里面知名度最高的一个,但是同时相对来说它的打包质量恐怕也 ...

  2. 洛谷 P1131 选择客栈

    题目描述 丽江河边有n 家很有特色的客栈,客栈按照其位置顺序从 1 到n 编号.每家客栈都按照某一种色调进行装饰(总共 k 种,用整数 0 ~ k-1 表示),且每家客栈都设有一家咖啡店,每家咖啡店均 ...

  3. 【CF700B】Connecting Universities(贪心,树上最短路)

    题意:给出一棵树上的2*k个节点,给他们配对,使得他们之间的距离和最大. 思路:一条边的两侧如果有一侧没有给定的节点就不会被经过…… 如果有1个节点就会被经过1次…… 如果两侧分别有x,y个给定节点就 ...

  4. Codeforces878C. Tournament

    $n \leq 50000$个人,每个人有$K \leq 10$个属性,现对每一个前缀问:进行比赛,每次任意两人比任意属性,小的淘汰(保证同一属性不会出现两个相同的数),最终有几个人有可能获胜. 明显 ...

  5. watch watch watch the video! I got almost addicted. Oh what a fuck!!!!

    http://v.huya.com/play/574329.html#relate_vid=570467

  6. power shell remoting

    Powershell Remoting建立在windows WinRM服务之上,可以一对一或一对多远程控制,也可以建立HTTP 或 HTTPS的“listeners”,使用WS-MAM协议接收远程传递 ...

  7. poj 1410 Intersection 线段相交

    题目链接 题意 判断线段和矩形是否有交点(矩形的范围是四条边及内部). 思路 判断线段和矩形的四条边有无交点 && 线段是否在矩形内. 注意第二个条件. Code #include & ...

  8. poj 3281(构图+网络流)

    Dining Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 14144   Accepted: 6425 Descripti ...

  9. 358. Rearrange String k Distance Apart

    /* * 358. Rearrange String k Distance Apart * 2016-7-14 by Mingyang */ public String rearrangeString ...

  10. Engine中如何进行七参数投影转换?

    来自:http://zhihu.esrichina.com.cn/?/question/6858 解决办法]:首先创建自定义geotransformation,然后用IGeometry.Project ...