HDU 5313 Bipartite Graph(二分图染色+01背包水过)
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.
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.
2
4 2
1 2
2 3
4 4
1 2
1 4
2 3
3 4
2
0
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背包水过)的更多相关文章
- hdu 5313 Bipartite Graph(dfs染色 或者 并查集)
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)
题意: Soda有一个n个点m条边的二分图, 他想要通过加边使得这张图变成一个边数最多的完全二分图. 于是他想要知道他最多能够新加多少条边. 注意重边是不允许的. 思路: 先将二分图着色,将每个连通分 ...
- HDU 5313 Bipartite Graph
题意:给一个二分图,问想让二分图变成完全二分图最多能加多少条边. 解法:图染色+dp+bitset优化.设最终的完全二分图两部分点集为A和B,A中点个数为x,B中点个数为y,边数则为x × y,答案即 ...
- POJ 1112 Team Them Up! 二分图判定+01背包
题目链接: http://poj.org/problem?id=1112 Team Them Up! Time Limit: 1000MSMemory Limit: 10000K 问题描述 Your ...
- HDU 3639 Bone Collector II(01背包第K优解)
Bone Collector II Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others ...
- HDU 2126 Buy the souvenirs (01背包,输出方案数)
题意:给出t组数据 每组数据给出n和m,n代表商品个数,m代表你所拥有的钱,然后给出n个商品的价值 问你所能买到的最大件数,和对应的方案数.思路: 如果将物品的价格看做容量,将它的件数1看做价值的话, ...
- HDU 1203 I NEED A OFFER! 01背包
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1203 解题思路:简单的01背包,用dp[i]表示花费不超过i时的最大可能性 状态转移方程 dp[i]= ...
- 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 ...
随机推荐
- Python 使用cx_freeze 生成exe文件
在python中比较常用的python转exe方法有三种,分别是cx_freeze,py2exe,PyInstaller.py2exe恐怕是三者里面知名度最高的一个,但是同时相对来说它的打包质量恐怕也 ...
- 洛谷 P1131 选择客栈
题目描述 丽江河边有n 家很有特色的客栈,客栈按照其位置顺序从 1 到n 编号.每家客栈都按照某一种色调进行装饰(总共 k 种,用整数 0 ~ k-1 表示),且每家客栈都设有一家咖啡店,每家咖啡店均 ...
- 【CF700B】Connecting Universities(贪心,树上最短路)
题意:给出一棵树上的2*k个节点,给他们配对,使得他们之间的距离和最大. 思路:一条边的两侧如果有一侧没有给定的节点就不会被经过…… 如果有1个节点就会被经过1次…… 如果两侧分别有x,y个给定节点就 ...
- Codeforces878C. Tournament
$n \leq 50000$个人,每个人有$K \leq 10$个属性,现对每一个前缀问:进行比赛,每次任意两人比任意属性,小的淘汰(保证同一属性不会出现两个相同的数),最终有几个人有可能获胜. 明显 ...
- watch watch watch the video! I got almost addicted. Oh what a fuck!!!!
http://v.huya.com/play/574329.html#relate_vid=570467
- power shell remoting
Powershell Remoting建立在windows WinRM服务之上,可以一对一或一对多远程控制,也可以建立HTTP 或 HTTPS的“listeners”,使用WS-MAM协议接收远程传递 ...
- poj 1410 Intersection 线段相交
题目链接 题意 判断线段和矩形是否有交点(矩形的范围是四条边及内部). 思路 判断线段和矩形的四条边有无交点 && 线段是否在矩形内. 注意第二个条件. Code #include & ...
- poj 3281(构图+网络流)
Dining Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 14144 Accepted: 6425 Descripti ...
- 358. Rearrange String k Distance Apart
/* * 358. Rearrange String k Distance Apart * 2016-7-14 by Mingyang */ public String rearrangeString ...
- Engine中如何进行七参数投影转换?
来自:http://zhihu.esrichina.com.cn/?/question/6858 解决办法]:首先创建自定义geotransformation,然后用IGeometry.Project ...