[Luo Gu P4251] play small convex matrix

Problem Description

Small square and small projections are friends, a small side to a small convex \ (n × m (n \ leq m) \) of the matrix A, and the required number n of the small projections is selected from the matrix, wherein any two the number can not be in the same row or the same column. Now small convex wondering, the number n k-elected in large numbers is the minimum number.

Input Format

The first row is read three integers n, m, k.

Subsequently n rows, each row has m numbers, j-th column element of the i-th row and j th number represents the matrix row i \ (A_ {i, j} \) .

Output Format

Output contains a line number n as the minimum value of k selected large numbers.

data range

For 20% of the data, \ (. 1 \ n-Leq \ Leq m \ Leq. 9 \)

For 40% of the data, \ (. 1 \ n-Leq \ Leq m \ Leq 22 is,. 1 \ n-Leq \ Leq 12 is \)

To 100% of the data, \ (. 1 \ Leq K \ n-Leq \ Leq m \ Leq 250,. 1 \ A_ Leq {I, J} \ Leq. 9 ^ 10 \)

link

Luo Valley

Resolve

Each row and each column can have only one point is selected, which limits the bipartite graph matching is very similar. You may wish to consider in this regard to.

First, the answer is found to monotonic, then a first mid-half, the matrix is greater than or equal to a number of mid, mid less than 0 is set. Then, the matrix can be generated as a new adjacency matrix, the maximum run bipartite graph matching. If the number of hits greater than or equal \ (n-mid + 1 \ ) , description can be found \ (n-mid + 1 \ ) over more than \ (MID \) a large number to meet the requirements, namely \ (MID \) small ; on the contrary too large.

Code

#include <iostream>
#include <cstdio>
#include <cstring>
#define N 252
using namespace std;
int n,m,k,i,j,g[N][N],a[N][N],match[N*N];
bool vis[N*N];
int read()
{
    char c=getchar();
    int w=0;
    while(c<'0'||c>'9') c=getchar();
    while(c<='9'&&c>='0'){
        w=w*10+c-'0';
        c=getchar();
    }
    return w;
}
bool dfs(int x)
{
    for(int i=1;i<=m;i++){
        if(g[x][i]&&!vis[n+i]){
            vis[n+i]=1;
            if(!match[n+i]||dfs(match[n+i])){
                match[n+i]=x;
                return 1;
            }
        }
    }
    return 0;
}
int hungary()
{
    int ans=0;
    for(int i=1;i<=n;i++){
        if(!match[i]){
            memset(vis,0,sizeof(vis));
            if(dfs(i)) ans++;
        }
    }
    return ans;
}
bool check(int x)
{
    memset(match,0,sizeof(match));
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++) g[i][j]=(a[i][j]<=x);
    }
    if(hungary()>=n-k+1) return true;
    return false;
}
int main()
{
    int l=1,r=0,mid,ans;
    n=read();m=read();k=read();
    for(i=1;i<=n;i++){
        for(j=1;j<=m;j++){
            a[i][j]=read();
            r=max(r,a[i][j]);
        }
    }
    while(l<=r){
        mid=(l+r)/2;
        if(check(mid)) ans=mid,r=mid-1;
        else l=mid+1;
    }
    printf("%d\n",ans);
    return 0;
}

Guess you like

Origin www.cnblogs.com/LSlzf/p/12220642.html