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篇celery使用
一.为什么要用celery celery是一个简单.灵活.可靠的,处理大量消息的分布式系统,并且提供维护这样一个系统的必须工具.他是一个专注于实时处理的任务队列,同时也支持任务调度. celery是异 ...
- hdu 4870 rating(高斯消元求期望)
Rating Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Sub ...
- 2017 UESTC Training for Data Structures-解题报告
题目链接:http://acm.uestc.edu.cn/#/contest/show/155 这个数据结构训练主要针对线段树,树转数组和并查集.比较适合刚入门数据结构的同学. 注意,因为后面题的代码 ...
- 标准C程序设计七---104
Linux应用 编程深入 语言编程 标准C程序设计七---经典C11程序设计 以下内容为阅读: <标准C程序设计>(第7版) 作者 ...
- win7快捷键和ubuntu快捷键
http://www.cnblogs.com/xfiver/archive/2010/12/08/1899905.html http://www.pc841.com/article/20121203- ...
- [转] 常用SQL查询语句
sunada 的原文地址 常用SQL查询语句 一.简单查询语句 1. 查看表结构 SQL>DESC emp; 2. 查询所有列 SQL>SELECT * FROM emp; 3. 查询指 ...
- 使用XtraGrid自定义列计算 z
绑定Master-Detail 关系 数据也是数据显示的一种方式,此实例使用后台代码创建数据源并绑定到gridcontrol. 其实方式参见:点击打开链接 先看效果图(默认方式) 直接给出后台代码,主 ...
- angular http ajax header
myAppModule.config(['$httpProvider', function($httpProvider) { $httpProvider.defaults.headers.common ...
- iOS -- YYText富文本
NSMutableAttributedString *text = [[NSMutableAttributedString alloc] initWithString: [NSString strin ...
- 页面登陆框老是乱乱的?banner跨页图片缩小之后总是在側面不能显示主要部分?哈哈~我来帮你忙~~
有banner背景图片和登陆框的html.css排布 目的:无论页面大小,背景图片都要居中(显示图片中间主要内容,而不是側面的一些东西),登陆框基本能在页面内显示. 盒子的排列应该是这种: <d ...