原文链接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. pointer & iterator

    pointer: address, use operator(*) to get/set the value 1) support operator(+,-), move to next posito ...

  2. Linux命令之top、ulimit、free

    1.[ulimit命令] ulimit命令用来限制系统用户对shell资源的访问. 假设有这样一种情况,当一台 Linux 主机上同时登陆了 10 个人,在系统资源无限制的情况下,这 10 个用户同时 ...

  3. win2008 C盘清理

    需要在Windows Server 2008上安装“桌面体验”才能使用磁盘清理工具,安装“桌面体验的”的具体步骤如下:   1. 打开“服务器管理器”——在“功能摘要”下,单击“添加功能”.   2. ...

  4. CSS基础入门

    css基础语法 一.CSS格式 选择器{ 属性名:属性值; 属性名:属性值; } 选择器负责圈定范围,要修改的元素集合,花括号内的声明由属性名和属性值组成(key:value)的形式,用于设定具体样式 ...

  5. js获取参数函数

  6. HSSFClientAnchor 参数说明

    pache POI  是用Java编写的免费开源的跨平台的 Java API,Apache POI提供API给Java程式对Microsoft Office格式档案读和写的功能. HSSFClient ...

  7. Confluence 6 编辑自定义 Decorators

    希望对 Confluence 的 decorator 进行编辑的话,你需要具有良好的 HTML 知识和能够理解  Velocity 模板语言. 希望编辑 decorator 文件: 进入  Confl ...

  8. vue之自行实现派发与广播-dispatch与broadcast

    要解决的问题 主要针对组件之间的跨级通信 为什么要自己实现dispatch与broadcast? 因为在做独立组件开发或库时,最好是不依赖第三方库 为什么不使用provide与inject? 因为它的 ...

  9. 浅谈js的join()方法

    简单描述:今天看同事的代码,看js的时候,看到了一个join()方法,我从来都没有用过,就查了查,第一次用就记录一下 正经的: 定义和用法 join() 方法用于把数组中的所有元素放入一个字符串. 元 ...

  10. 小学生都看得懂的C语言入门(5): 指针

    现在已经学到C语言的后面了, 快学完咯.... (一)取地址运算 先来看一下sizeof 计算所占字节 #include<stdio.h> int main() { int a; a=; ...