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

Bipartite Graph

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 840    Accepted Submission(s): 285

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

题目大意:跟你一个二分图。n个顶点,m条边。问你再添加多少条边,让这个二分图变成完全二分图。

解题思路:为了让加的边尽量多,那么就要保证该二分图两侧的顶点个数尽量相同。那么我们统计出各个二分图连通块两边各有多少个顶点,最后用dp来得出两边相差最少时,两边会有多少个顶点。最后套个公式就可以了。本来用二维dp01背包。但是超时。然后就换用了bitset进行优化。

// bitset::reset
#include <iostream>       // std::cout
#include <string>         // std::string
#include <bitset>         // std::bitset

int main ()
{
  std::bitset<4> foo (std::string("1011"));

  std::cout << foo.reset(1) << ‘\n‘;    // 1001
  std::cout << foo.reset() << ‘\n‘;     // 0000

  return 0;
}

// bitset::operator[]
#include <iostream>       // std::cout
#include <bitset>         // std::bitset

int main ()
{
  std::bitset<4> foo;

  foo[1]=1;             // 0010
  foo[2]=foo[1];        // 0110

  std::cout << "foo: " << foo << ‘\n‘;

  return 0;
}

  

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<bitset>
#include<vector>
using namespace std;
const int maxn=1e4+20;
#define min(a,b) ((a)<(b)?(a):(b))
vector<int>G[maxn];
int color[maxn],d[maxn][3];
int n,m;
void dfs(int cc,int u,int col){
  //  printf("%d---%d----\n",u,cc);
    if(!color[u]){
        color[u]=col;
        d[cc][col+1]++;
    }
    for(int i=0;i<G[u].size();i++){
        int v=G[u][i];
        if(!color[v]){
            dfs(cc,v,-col);
        }
    }
}
int main(){
    int t,a,b;
    scanf("%d",&t);
    while(t--){
        scanf("%d%d",&n,&m);
        for(int i=0;i<m;i++){
            scanf("%d%d",&a,&b);
            G[a].push_back(b);
            G[b].push_back(a);
        }
        int c=0;
        for(int i=1;i<=n;i++){
            if(!color[i]){
                c++;
                dfs(c,i,1);
            }
        }
        const int V=5001;
        bitset<V>dp;
        dp.reset();
        dp[0]=1;
        for(int i=1;i<=c;i++){
            dp=(dp<<d[i][0])|(dp<<d[i][2]);
        }
        int k=1;
        for(int i=n/2;i>=1;i--){
            if(dp[i]){
                k=i;
                break;
            }
        }
        printf("%d\n",(n-k)*k-m);
        for(int i=0;i<=n;i++)
            G[i].clear();
        memset(color,0,sizeof(color));
        memset(d,0,sizeof(d));
    }
    return 0;
}

/*
8
8 6
1 2
2 3
2 4
5 6
6 7
6 8
*/

  

时间: 2024-10-20 11:57:07

HDU 5313——Bipartite Graph——————【二分图+dp+bitset优化】的相关文章

HDU 5313 Bipartite Graph

题意:给一个二分图,问想让二分图变成完全二分图最多能加多少条边. 解法:图染色+dp+bitset优化.设最终的完全二分图两部分点集为A和B,A中点个数为x,B中点个数为y,边数则为x × y,答案即为x × y - m,那么用dp计算集合A中点个数的可能性.先用图染色计算每个连通分量里两种颜色点的个数,用dp[i][j]表示加入第i个连通分量时A集合中有j个点的可能性,可能为1,不可能为0,设联通分量为p,可以得到转移方程为dp[i][j] = dp[i - 1][j - p[i][0]] |

hdu 5313 Bipartite Graph 完全二分图 深搜 bitset应用

Bipartite Graph Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 577    Accepted Submission(s): 154 Problem Description Soda has a bipartite graph with n vertices and m undirected edges. Now he

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

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

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

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

HDU 5313 Bipartite Graph (二分图着色,dp) TLE!!!

题意:Soda有一个$n$个点$m$条边的二分图, 他想要通过加边使得这张图变成一个边数最多的完全二分图. 于是他想要知道他最多能够新加多少条边. 注意重边是不允许的. 思路:二分图着色这个简单,主要是dp,还有时间限制.我觉得应该是找出所有连通分量,每个连通分量两边的点数存起来,后面统一进行DP.但是!!时间仅有1s,而且还100个例子,就是说大概要在100万的复杂度才行,可是有1万个点,当m=5000时,这就不行. 我不懂这道题如何下手才能保证一定正确且不超时,应该优化得很厉害~ 贴一个我认

hdu 5313 Bipartite Graph(dfs+背包)

题意:n个点m条边,每条边的两个端点已知,求构成完全二分图能加的最多的边数: 参考:http://blog.csdn.net/acmhonor/article/details/47072399 思路:并不是一个二分图的题... n个点构成完全二分图是,两边的点数差值最小时边数最多(X+Y=n,求max(x*y)): 即在给定一些边的情况下,要求的是将点分在两个集合中数量差最小的情况: 先求出每个联通块中的点的情况,考虑孤立点的个数,通过贪心实现剪枝: 非贪心的情况使用背包,背包容量为n/2,推出

HDU 5890 Eighty seven(DP+bitset优化)

题目链接 Eighty seven 背包(用bitset预处理)然后对于每个询问O(1)回答即可. 预处理的时候背包. 1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 #define rep(i, a, b) for(int i(a); i <= (b); ++i) 6 #define dec(i, a, b) for(int i(a); i >= (b); --i) 7 8 const int N = 52; 9 1

hdu5313Bipartite Graph(二分图染色+DP(bitset优化))

题意:给n个点m条边,问最多可以添加几条边使图为完全二分图 分析:如果二分图没有限制,看到是两边分别为n/2个点和n-n/2个点的最优但是可   能出现大于此点的情况,比如n=4,m=3,边为1 2,1 3,1 4.此时完全二分图边最多为3,所以要求得二分图左边或者右边可达到的离n/2最近的点数是多少为最优解,于是采用染色分别求出各个联通快的2种颜色的各个点数,然后用推出能达到的点数,这里dp[i]的下一个状态是dp[i+1]+d[i+1][0]和dp[i+1][1](dp[i]为前i个二分图的

bzoj3687简单题(dp+bitset优化)

3687: 简单题 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 861  Solved: 399[Submit][Status][Discuss] Description 小呆开始研究集合论了,他提出了关于一个数集四个问题:1.子集的异或和的算术和.2.子集的异或和的异或和.3.子集的算术和的算术和.4.子集的算术和的异或和.    目前为止,小呆已经解决了前三个问题,还剩下最后一个问题还没有解决,他决定把这个问题交给你,未来的集训队队员来实现