• [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
  • 相关阅读:
    xshell常用命令
    linux传输文件命令: rz 和 sz
    使用openssh-clients的scp命令来传输文件
    RabbitMQ初学之二:直接发送消息到队列
    [App]华为P6设置与Xamarin Studio连通测试
    [Boost]图形处理库Boost::Polygon
    [App]Taste VS2015 && Android Studio
    [Linux&Vim]输入输出流
    [SSD大法好]神舟K480-I5-D3鸟枪换炮M6S
    [IoLanguage]Io Tutorial[转]
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/13999873.html
Copyright © 2020-2023  润新知