zoukankan      html  css  js  c++  java
  • bzoj4443: [Scoi2015]小凸玩矩阵

    太久没搞网络流,又被坑了一发死循环。。(这次是对cur[]初始化没对。以后直接for S到T不就好了嘛!)

    先看数据量。诶,才250,肯定n三方。搜索不行,dp不行,贪心不行,二分图网络流?恩,有可能,先放一边去。

    然而正解就是二分+二分图匹配。

    二分答案,二分图匹配看是否存在大等n-k+1个匹配。

    基本上每当题目中有限制不能同行不能同列的时候都是二分图左边为行,右边为列来匹配的。(我怎么就是不长记性呢,又被坑了

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define INF 1e9+5
     4 #define N 70005
     5 int n,m,k,d[N],cur[N],S,T,cnt,z[255][255],head[N];
     6 bool vis[N];
     7 queue<int>q;
     8 struct edges{
     9     int fr,to,cap,flow,next;
    10 }e[4*N];
    11 void inser(int u,int v,int c){
    12     e[cnt]=(edges){u,v,c,0,head[u]};head[u]=cnt++;
    13     e[cnt]=(edges){v,u,0,0,head[v]};head[v]=cnt++;
    14 }
    15 bool bfs(){
    16     memset(vis,0,sizeof(vis)); 
    17     vis[S]=1; q.push(S); d[S]=0;
    18     while(!q.empty()){
    19         int x=q.front(); q.pop();
    20         for(int i=head[x];i>=0;i=e[i].next)
    21             if(!vis[e[i].to] && e[i].cap>e[i].flow) vis[e[i].to]=1,d[e[i].to]=d[x]+1,q.push(e[i].to);
    22     }
    23     return vis[T];
    24 }
    25 int dfs(int x,int a){
    26     if(x==T || !a) return a;
    27     int f,flow=0;
    28     for(int& i=cur[x];i>=0;i=e[i].next)
    29         if(d[e[i].to]==d[x]+1 && (f=dfs(e[i].to,min(a,e[i].cap-e[i].flow)))>0){
    30           e[i].flow+=f; flow+=f; e[i^1].flow-=f; a-=f;
    31         if(!a) break;
    32         }
    33     return flow;
    34 }
    35 int maxflow(){
    36     int flow=0;
    37     while(bfs()){
    38         for(int i=S;i<=T;i++) cur[i]=head[i];
    39         flow+=dfs(S,INF);
    40     }
    41     return flow;
    42 }
    43 void build(int x){
    44     memset(head,-1,sizeof(head)); cnt=0;
    45     for(int i=1;i<=n;i++) inser(S,i,1);
    46     for(int i=1;i<=m;i++) inser(i+n,T,1);
    47     for(int i=1;i<=n;i++)
    48        for(int j=1;j<=m;j++)
    49          if(z[i][j]<=x) inser(i,j+n,1);
    50 } 
    51 int main(){
    52     scanf("%d%d%d",&n,&m,&k); 
    53     S=0; T=n+m+1;
    54     for(int i=1;i<=n;i++)
    55        for(int j=1;j<=m;j++)
    56           scanf("%d",&z[i][j]);
    57     int l=1,r=INF;
    58     while(l<r){
    59         int mid=(l+r)>>1; build(mid);
    60         if(maxflow()<n-k+1) l=mid+1;
    61         else r=mid;
    62     }
    63     printf("%d
    ",l);
    64     return 0;
    65 }
  • 相关阅读:
    Sql Server 2008卸载后再次安装一直报错
    listbox 报错 Cannot have multiple items selected when the SelectionMode is Single.
    Sql Server 2008修改Sa密码
    学习正则表达式
    Sql Server 查询第30条数据到第40条记录数
    Sql Server 复制表
    Sql 常见面试题
    Sql Server 简单查询 异步服务器更新语句
    jQuery stop()用法以及案例展示
    CSS3打造不断旋转的CD封面
  • 原文地址:https://www.cnblogs.com/enigma-aw/p/5971291.html
Copyright © 2011-2022 走看看