zoukankan      html  css  js  c++  java
  • [最大独立集]JZOJ 5394 列队

    Description

            Sylvia是一个热爱学习的女孩子。
            在平时的练习中,他总是能考到std以上的成绩,前段时间,他参加了一场练习赛,众所周知,机房是一个 的方阵。这天,他又打爆了std,感到十分无聊,便想要hack机房内同学的程序,他会挑选一整行或一整列的同学进行hack ( 而且每行每列只会hack一次 ),然而有些同学不是那么好惹,如果你hack了他两次,他会私下寻求解决,Sylvia十分害怕,只会hack他们一次。假设Sylvia的水平十分高超,每次hack都能成功,求他最 多能hack多少次?
     

    Input

       第一行两个数 表示机房的大小和不好惹的同学个数
      接下来x行,每行两个数 表示不好惹的同学坐标

    Output

    一个数表示最多hack多少次
     

    Sample Input

    2 1
    1 1

    Sample Output

    6
    
    样例说明
         他可以hack第一行、第二行、第二列一共6次
     

    Data Constraint

    数据规模和约定
    对于20%的数据  n<=10,  x<=100
    对于40%的数据  n<=20 , x<=400
    对于100%的数据 n<=1000 , x<=4000
    1<=x,y<=n且同一个点不会重复出现

    分析

    这题我们发现如果不好惹的同学选了行hack就不能列hack,这个是不是很像二分图匹配呢~(个鬼,想到的是2-sat)

    咳咳,那么这个其实看了一会儿会发现就是一个最大独立集问题,行向列连个边就好了,跑下匈牙利就好了

    最大独立集数=点数-最大匹配数

    #include <iostream>
    #include <cstdio>
    #include <memory.h>
    using namespace std;
    const int N=1e3+10;
    int connect[N];
    bool visit[N],to[N][N];
    int n,m,ans;
    
    bool XYL(int u) {
        if (visit[u]) return 0;
        visit[u]=1;
        for (int i=1;i<=n;i++)
            if (to[u][i]&&(!connect[i]||XYL(connect[i]))) {
                connect[i]=u;
                return 1;
            }
        return 0;
    }
    
    int main() {
        freopen("phalanx.in","r",stdin);
        freopen("phalanx.out","w",stdout);
        scanf("%d%d",&n,&m);
        for (int i=1;i<=m;i++) {
            int x,y;
            scanf("%d%d",&x,&y);
            to[x][y]=1;
        }
        ans=n*2;
        for (int i=1;i<=n;i++) {
            memset(visit,0,sizeof visit);
            ans-=XYL(i);
        }
        printf("%d",ans*n);
    }
    View Code
    在日渐沉没的世界里,我发现了你。
  • 相关阅读:
    yum管理工具
    ansible简介,简单实用
    ssh服务简介及应用与服务的进程的类型
    keepliave
    NFS
    编译安装redis4.0
    redis多实例和高可用
    NTP时间服务
    ssl简介与openssl的使用
    一些高效学习方法-牛人是怎么来的
  • 原文地址:https://www.cnblogs.com/mastervan/p/9872978.html
Copyright © 2011-2022 走看看