[atARC099E]Independence

考虑这张图的反图,相当于这两个集合内部没有边,这也就是二分图的限制

换言之,我们要将这张图黑白染色(不能则为-1),$x$即为某种颜色的数个数

对于一个联通块,记连通块大小为$sz$,则白色点个数为$w$或$sz-w$(交换两种颜色)

背包转移即可,时间复杂度为$o(n^{2})$,可以通过此题

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 #define N 705
 4 struct ji{
 5     int nex,to;
 6 }edge[N*N]; 
 7 bitset<N>f;
 8 int E,n,m,x,y,ans,head[N],e[N][N],vis[N];
 9 void add(int x,int y){
10     edge[E].nex=head[x];
11     edge[E].to=y;
12     head[x]=E++;
13 }
14 int dfs(int k,int p){
15     if (vis[k]>=0)return vis[k]==p;
16     x+=(!p);
17     y+=p;
18     vis[k]=p;
19     for(int i=head[k];i!=-1;i=edge[i].nex)
20         if (!dfs(edge[i].to,p^1))return 0;
21     return 1;
22 }
23 int c(int k){
24     return k*(k-1)/2;
25 }
26 int main(){
27     scanf("%d%d",&n,&m);
28     memset(head,-1,sizeof(head));
29     for(int i=1;i<=m;i++){
30         scanf("%d%d",&x,&y);
31         e[x][y]=e[y][x]=1;
32     }
33     for(int i=1;i<=n;i++)
34         for(int j=1;j<=n;j++)
35             if ((i!=j)&&(!e[i][j]))add(i,j);
36     memset(vis,-1,sizeof(vis));
37     f[0]=1;
38     for(int i=1;i<=n;i++)
39         if (vis[i]<0){
40             x=y=0;
41             if (!dfs(i,0)){
42                 printf("-1");
43                 return 0;
44             }
45             f=((f<<x)|(f<<y));
46         }
47     ans=c(n);
48     for(int i=1;i<n;i++)
49         if (f[i])ans=min(ans,c(i)+c(n-i));
50     printf("%d",ans);
51 }
View Code

 

posted @ 2020-11-18 14:59  PYWBKTDA  阅读(95)  评论(0编辑  收藏  举报