hdu5313 Bipartite Graph

题意描述:

有一个n个点m条边的二分图,通过加边使得这张图变成一个边数最多的完全二分图. 最多能够新加多少条边. 注意重边是不允许的.

解题思路:

1、先对二分图染色(dfs),统计二分图中每个连通块(注意:这个二分图并不一定连通)中黑色和白色的数量(黑、白是相对的,不同连通块之间的黑、白没有联系);

2、从每个连通块中选出黑或白的数量作为整个二分图中白色的那组,根据题目描述我们只需要找到怎样分组才能使完全二分图的边数最多(显然对于总共n个顶点的

二分图,如果两组顶点各一半时能使总的边数最大),因此我们可以使用dp得出各种分组情况。

3、由于数据10000,此处采用bitset进行优化,通过bitset运算dp出所有可能的分组情况,然后取其中使总的边数最大的情况即可

#include <cstdio>
#include <cstring>
#include <vector>
#include <bitset>
#define MAXN 10010
using namespace std;

struct node
{
    int a,b;
    node(int a,int b):a(a),b(b) {};
};

int n,m;
int an,bn;///统计每次dfs时黑点和白点的数量
vector<int> g[MAXN];
bool flag[MAXN];
vector<node> ans;///保存二分图中每个连通块的黑点和白点数量

void dfs(int rt,bool f);

int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        memset(g,0,sizeof(g));
        int x,y;
        for(int i=1; i<=m; ++i)
        {
            scanf("%d%d",&x,&y);
            g[x].push_back(y);
            g[y].push_back(x);
        }
        memset(flag,false,sizeof(flag));
        ans.clear();
        for(int i=1; i<=n; ++i)
        {
            if(!flag[i])
            {
                an=0,bn=0;
                flag[i]=true;
                dfs(i,true);
                ans.push_back(node(an,bn));
            }
        }
        bitset<MAXN> cur;
        cur.set(0);///设置第0位为1
        int len=ans.size();
        for(int i=0; i<len; ++i)///dp得到所有可能的黑点和白点的数量
            <span style="color:#ff0000;">cur=cur<<ans[i].a|cur<<ans[i].b;///状态转移方程,cur保存了所有可能的组合</span>

        int anst=0;
        for(int i=1; i<n; ++i)
            if(cur[i])
                anst=max(anst,(n-i)*i-m);
        printf("%d\n",anst);
    }
    return 0;
}
void dfs(int rt,bool f)
{
    if(f)an++;
    else bn++;
    int len=g[rt].size();
    for(int i=0; i<len; ++i)
    {
        if(!flag[g[rt][i]])
        {
            flag[g[rt][i]]=true;
            dfs(g[rt][i],!f);
        }
    }
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-12 09:50:45

hdu5313 Bipartite Graph的相关文章

HDU5313——DP+vector——Bipartite Graph

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: T

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(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(二分图染色+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——————【二分图+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 w

hdu5354 Bipartite Graph

分治+并查集.假设要求[L,mid]的答案,那么很明显,如果一条边的两个端点都>mid的话或者一个端点>mid一个端点<L,说明询问[L,mid]这个区间中任何一点时候,这一条边都是连接的,否则的话递归下去处理.[mid+1,R]同理. 一个图不是二分图的话说明存在奇环,奇环可以用并查集处理.这里的并查集不使用路径压缩而使用按轶合并.并查集的还原操作可以用一个栈记录每次合并时的具体操作,然后按序还原即可. 代码 1 #include<cstdio> 2 #include<

[hdu 5354] Bipartite Graph 分治 并查集

题意 给定一张 $n$ 个点, $m$ 条边的无向图. 问删去每个点后, 原图是不是二分图. $1 \le n, m \le {10} ^ 5$ . 分析 一个图是二分图 $\Leftrightarrow$ 图中不存在奇环. 判定一个图是不是二分图, 可以使用并查集, 多维护一个当前点与父亲的关系的量 bond . 删除每一个点, 我们有两种维度: 区间加法, 区间减法. 这里考虑区间加法, 即考虑分治. 由于要支持撤销, 所以使用按秩合并的并查集. 注意按照大小合并... 按深度合并会 TLE

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

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5354 题意:求删去每个点后图是否存在奇环(n,m<=1e5) 解法:很经典的套路,和这题一样:http://www.cnblogs.com/spfa/p/7358672.html CDQ套并查集. 这题最开始是看了南神的代码才懂的,http://blog.csdn.net/hdu2014/article/details/47450709    因为要判断每一个点,而且一旦一个点之外的几个点形成了奇环

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]] |