原文链接https://www.cnblogs.com/zhouzhendong/p/9224878.html

题目传送门 - ARC099 E - Independence

题意

  给定一个有 $n$ 个节点, $m$ 条边的无向图,保证没有自环和重边。

  请你把所有的 $n$ 个节点分成两组,同组中的任意两个节点之间都有边直接连接。

  问连接同组节点的总边数最小为多少?如果不存在合法的划分方案,则输出 $-1$ 。

  数据范围: $n\leq 700, 0\leq m\leq \cfrac{n(n-1)}2 $

题解

  考虑到同组节点必须形成完全子图,这个性质和二分图恰好相反。

  所以我们考虑在其补图上找一个二分图,并求出这个二分图两侧节点数有哪些可能。

  对于每一个连通分量,我们进行黑白染色。如果不支持黑白染色,那么输出 $-1$ 。

  (假设最终的二分图分为左右两侧)

  记两种颜色的节点个数分别为 $x,y$ ,那么,既可以把 $x$ 个节点放入左侧,也可以把 $y$ 个节点放入左侧。

  所有的连通分量的结果综合一下,变成一个背包问题,我用了 $DP$ ,然后赛后看大神们直接用 $bitset$,方便极了。

  对于得到的所有可能的左侧节点数,我们算一下答案取 $min$ 即可。

代码

#include <bits/stdc++.h>
using namespace std;
const int N=2005;
int n,m;
int g[N][N];
int dp[N],e[N],vis[N],x,y,f=0;
void dfs(int p,int t){
if (vis[p]){
if (vis[p]!=t+1)
f=1;
return;
}
vis[p]=t+1;
if (t)
x++;
else
y++;
for (int i=1;i<=n;i++)
if (i!=p&&!g[p][i])
dfs(i,t^1);
}
int calc(int x){
return x*(x-1)/2;
}
int main(){
scanf("%d%d",&n,&m);
for (int i=1,a,b;i<=m;i++){
scanf("%d%d",&a,&b);
g[a][b]=g[b][a]=1;
}
memset(dp,0,sizeof dp);
dp[0]=1;
for (int i=1;i<=n;i++){
if (vis[i])
continue;
x=0,y=0;
dfs(i,0);
memset(e,0,sizeof e);
for (int j=n;j>=0;j--)
e[j+x]|=dp[j],e[j+y]|=dp[j];
for (int j=0;j<=n;j++)
dp[j]=e[j];
}
if (f){
puts("-1");
return 0;
}
int ans=n*n*2;
for (int i=0;i<=n;i++)
if (dp[i])
ans=min(ans,calc(i)+calc(n-i));
printf("%d",ans);
return 0;
}

  

AtCoder Regular Contest 099 (ARC099) E - Independence 二分图的更多相关文章

  1. AtCoder Regular Contest 099

    AtCoder Regular Contest 099 C - Minimization 题意 题意:给出一个n的排列.每次操作可以使一段长度为K的连续子序列变成该序列的最小数.求最少几次使得整个数列 ...

  2. AtCoder Regular Contest 099 C~E

    C - Minimization 枚举就可以了 因为最后一定会变成1,所以第一次操作的区间就包含1会比较优,然后枚举1在第一次操作区间里排第几个取min即可 #include<iostream& ...

  3. AtCoder Regular Contest 061

    AtCoder Regular Contest 061 C.Many Formulas 题意 给长度不超过\(10\)且由\(0\)到\(9\)数字组成的串S. 可以在两数字间放\(+\)号. 求所有 ...

  4. AtCoder Regular Contest 094 (ARC094) CDE题解

    原文链接http://www.cnblogs.com/zhouzhendong/p/8735114.html $AtCoder\ Regular\ Contest\ 094(ARC094)\ CDE$ ...

  5. AtCoder Regular Contest 092

    AtCoder Regular Contest 092 C - 2D Plane 2N Points 题意: 二维平面上给了\(2N\)个点,其中\(N\)个是\(A\)类点,\(N\)个是\(B\) ...

  6. AtCoder Regular Contest 093

    AtCoder Regular Contest 093 C - Traveling Plan 题意: 给定n个点,求出删去i号点时,按顺序从起点到一号点走到n号点最后回到起点所走的路程是多少. \(n ...

  7. AtCoder Regular Contest 094

    AtCoder Regular Contest 094 C - Same Integers 题意: 给定\(a,b,c\)三个数,可以进行两个操作:1.把一个数+2:2.把任意两个数+1.求最少需要几 ...

  8. AtCoder Regular Contest 095

    AtCoder Regular Contest 095 C - Many Medians 题意: 给出n个数,求出去掉第i个数之后所有数的中位数,保证n是偶数. \(n\le 200000\) 分析: ...

  9. AtCoder Regular Contest 102

    AtCoder Regular Contest 102 C - Triangular Relationship 题意: 给出n,k求有多少个不大于n的三元组,使其中两两数字的和都是k的倍数,数字可以重 ...

随机推荐

  1. 《Spring5官方文档》新功能(4,3)

    <Spring5官方文档>新功能 原文链接 译者:supriseli Spring框架的新功能 这一章主要提供Spring框架新的功能和变更. 升级到新版本的框架可以参考.Spring g ...

  2. 深入Golang调度器之GMP模型

    前言 随着服务器硬件迭代升级,配置也越来越高.为充分利用服务器资源,并发编程也变的越来越重要.在开始之前,需要了解一下并发(concurrency)和并行(parallesim)的区别. 并发:  逻 ...

  3. hadoop常用命令详细解释

    hadoop命令分为2级,在linux命令行中输入hadoop,会提示输入规则 Usage: hadoop [--config confdir] COMMAND where COMMAND is on ...

  4. WebSocket异步通讯,实时返回数据

    第一种方式 // 服务端: //var listener = new HttpListener(); // listener.Prefixes.Add("http://*:8080/&quo ...

  5. git的学习笔记(一):git本地操作

    1.Git介绍 Git是一个开源的分布式版本控制软件,用以有效.高速的处理从很小到非常大的项目版本管理. Git 最初是由Linus Torvalds设计开发的,用于管理Linux内核开发. Git ...

  6. es6简单介绍

    1.ECMAScript 6 简介 2.let和const命令 3.变量的解构赋值 4.字符串的扩展之模板字符串 5.正则的扩展 6.数值的扩展 7.函数的扩展 8.数组的扩展 9.对象的扩展 10. ...

  7. mysql 各种关系代数的使用

    连接(JOIN) 选择运算表示为: R⋈S ,其中R和S为不同的两个关系 连接运算是选取两个指定关系中的属性满足给定条件的元祖连接在一起来组成一个新的关系 数学形式: JOIN 关系名1 AND 关系 ...

  8. 51nod1158 最大子矩形 单调栈应用

    #include<iostream> #include<cstring> #include<cstdio> using namespace std; ][6],m, ...

  9. Python元组(tuple)

    元组(tuple)是Python中另一个重要的序列结构,与列表类型,也是由一系列按特定顺序排列的元素组成,但是他是不可变序列.在形式上元组的所有元素都放在"()"中,两个元素使用& ...

  10. python 之 列表与字典

    1.4 列表与字典 列表与字典,这两种类型,都是各种类型的集合,以列表为例,如果列表中包含列表,就形成嵌套. 这两种类型几乎是所有python脚本的主要工作组件 . 这种结构信息是可变的可修改的.不像 ...