给出一个二分图,求添加最多的边数 变成一个完全二分图
若两个点集个数越接近,边的数量越大
染色联通块得到k组两个点集的数量
然后用bitset搞= =
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <string>
#include <iostream>
#include <algorithm>
#include <sstream>
#include <cmath>
using namespace std;
#include <queue>
#include <stack>
#include <vector>
#include <deque>
#include<bitset>
#include <set>
#include <map>
#define clc(arr, val) memset(arr, val, sizeof(arr))
#define FOR(i,a,b) for(int i=a;i<=b;i++)
#define IN freopen ("in.txt" , "r" , stdin);
#define OUT freopen ("out.txt" , "w" , stdout);
typedef long long LL;
typedef unsigned long long ULL;
const int MAXN = 600127;
const int MAXM = 6000010;
const int N = 30127;
const int M = 200000;
const int INF = 0x3f3f3f3f;
const LL mod = (LL)1<<32;
const double eps= 1e-8;
const double pi=acos(-1.0);
#define lson l,m, rt<<1
#define rson m+1,r,rt<<1|1
struct node
{
int v,next;
}edge[423467];
int head[10100],tol;
void add(int u,int v)
{
edge[tol].v=v;edge[tol].next=head[u];
head[u]=tol++;
}
int num[3],vis[10100];
int hh[10100][2],q;
void init()
{
memset(head,-1,sizeof(head));
memset(vis,0,sizeof(vis));
tol=0;
}
int dfs(int u,int pre,int sta)
{
num[sta]++;
vis[u]=1;
for(int i=head[u];~i;i=edge[i].next)
{
if(pre==edge[i].v) continue;
if(vis[edge[i].v]) continue;
dfs(edge[i].v,u,3-sta);
}
}
int main()
{
int t,n,m,a,b;
cin>>t;
while(t--)
{
cin>>n>>m;
init();
for(int i=0;i<m;i++)
{
scanf("%d%d",&a,&b);
add(a,b);
add(b,a);
}
q=0;
for(int i=1;i<=n;i++)//染色
{
if(!vis[i])
{
memset(num,0,sizeof(num));
dfs(i,i,1);
hh[q][0]=num[1];
hh[q++][1]=num[2];
}
}
bitset<10100> f;
f[0]=1;
for(int i=0;i<q;++i)
f=(f<<hh[i][0])|(f<<hh[i][1]);
int ans=0;
for(int i=1;i<n;++i)
if(f[i])
ans=max(ans,i*(n-i));
printf("%d\n",ans-m);
}
return 0;
}