zoukankan      html  css  js  c++  java
  • 小凸玩矩阵

    简单题,我秒了。
    (k=n*m-k),等于询问(k)小值。
    考虑二分,二分答案(md),考虑判定是否存在一种方案使得(k)小值(leq md)
    事实上就是判定是否存在一个选数方案使得(leq md)的数数量(geq k)
    题目中一行一列最多只能选择一个数,用(1)流量限制。
    考虑二分图。把每一行/列拆成s->行,列->t的两条流量为(1)的边。
    用一条(s->t)(1)流表示选择一个格子,对于一个格子((i,j))如果(leq md),则左边(i)到右边(j)连一条边。

    #include<bits/stdc++.h>
    using namespace std;
    #define N 200010
    #define M 200010
    int h[M],nxt[M],v[M],w[M],s,t,dep[M],ec,n,m,k,p[N],a[500][500];
    void add(int a,int b,int c){v[++ec]=b;w[ec]=c;nxt[ec]=h[a];h[a]=ec;}
    void adj(int a,int b,int c){
    	add(a,b,c);
    	add(b,a,0);
    }
    bool bfs(){
        queue<int>q;
    	q.push(s);
        for(int i=0;i<=t;i++)
        	dep[i]=0;
    	dep[s]=1;
        while(!q.empty()){
            int x=q.front();q.pop();
            for(int i=h[x];i;i=nxt[i])
                if(w[i]&&!dep[v[i]]){
                	dep[v[i]]=dep[x]+1;
    				q.push(v[i]);
                	if(v[i]==t)
    					return 1;
    			}
        }
    	return 0;
    }
    int dfs(int x,int dis){
        if(x==t)
    		return dis;
    	int tp=dis;
        for(int i=h[x];i;i=nxt[i])
            if(dep[v[i]]==dep[x]+1&&w[i]){
                int f=dfs(v[i],min(tp,w[i]));
                if(!f)
    				dep[v[i]]=0;
                tp-=f;
                w[i]-=f;
    			w[i^1]+=f;
                if(!tp)
    				break;
            }
        return dis-tp;
    }
    int din(){
        int aans=0;
        while(bfs()){
        	int v;
        	while(v=dfs(s,1e9))
    			aans+=v;
    	}
        return aans;
    }
    int pd(int md){
    	ec=1;
    	memset(h,0,sizeof(h));
    	for(int i=1;i<=n;i++)
    		for(int j=1;j<=m;j++)
    			if(a[i][j]<=md)
    				adj(i,j+n,1);
    	t=n+1+m;
    	for(int i=1;i<=n;i++)
    		adj(s,i,1);
    	for(int i=1;i<=m;i++)
    		adj(i+n,t,1);
    	return din()>=n-k+1;
    }
    signed main(){
    	scanf("%d%d%d",&n,&m,&k);
    	for(int i=1;i<=n;i++)
    		for(int j=1;j<=m;j++)
    			scanf("%d",&a[i][j]);
    	int l=1,r=1e9,ans=1;
    	while(l<=r){
    		int md=(l+r)/2;
    		if(pd(md)){
    			r=md-1;
    			ans=md;
    		}
    		else
    			l=md+1;
    	}
    	printf("%d",ans);
    }
    
    
  • 相关阅读:
    Linux
    Linux下安装和使用FTp
    国内maven库镜像(阿里云)
    Java build path && Deployment assembly && 编译路径 && 发布路径
    关于Eclipse编译和执行文件时,后台默认执行动作的思考
    spring核心框架体系结构(各个jar包作用)
    OpenSessionInViewFilter的作用及原理
    Spring事务失效的原因
    解决Spring框架的Dao层改用@Repository注解,无法使用JdbcDaoSupport的问题
    JTA 深度历险
  • 原文地址:https://www.cnblogs.com/ctmlpfs/p/14951890.html
Copyright © 2011-2022 走看看