zoukankan      html  css  js  c++  java
  • bzoj 4443 [Scoi2015]小凸玩矩阵 网络流,二分

    [Scoi2015]小凸玩矩阵

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 1564  Solved: 734
    [Submit][Status][Discuss]

    Description

    小凸和小方是好朋友,小方给小凸一个N*M(N<=M)的矩阵A,要求小秃从其中选出N个数,其中任意两个数字不能在同一行或同一列,现小凸想知道选出来的N个数中第K大的数字的最小值是多少。
     

    Input

    第一行给出三个整数N,M,K
    接下来N行,每行M个数字,用来描述这个矩阵
     

    Output

    如题 
     

    Sample Input

    3 4 2
    1 5 6 6
    8 3 4 3
    6 8 6 3

    Sample Output

    3

    HINT

    1<=K<=N<=M<=250,1<=矩阵元素<=10^9

     判断是否能取出N-K+1个小于等于ans的数
    但是能取出N-K+1个小于等于ans的数,不代表能取出K个大于等于ans的数呀
    注意,最后得到的ans是最小的存在N-K个比它小的数的数

    如果连最小的ans都取不到,那么更大的ans也取不到呀

    判断的话若(i,j)小于等于x,则第i行向第j列连边,然后跑最大流看是否大于等于n-k+1即可

      1 #include<iostream>
      2 #include<cstdlib>
      3 #include<cstdio>
      4 #include<cstring>
      5 #include<cmath>
      6 #include<ctime>
      7 #include<algorithm>
      8 #include<iomanip>
      9 #include<vector>
     10 #include<stack>
     11 #include<queue>
     12 #include<map>
     13 #include<set>
     14 #include<bitset>
     15 using namespace std;
     16 #define MAXN 1010
     17 #define MAXM 150010
     18 #define ll long long
     19 #define INF 1000000000
     20 #define MOD 1000000007
     21 #define eps 1e-8
     22 struct vec{
     23     int to;
     24     int fro;
     25     int v;
     26 };
     27 vec mp[MAXM];
     28 int tai[MAXN],cnt=1;
     29 int q[MAXM],hd,tl;
     30 int s,t;
     31 int cur[MAXN];
     32 int d[MAXN];
     33 int ans;
     34 inline void be(int x,int y,int z){
     35     mp[++cnt].to=y;
     36     mp[cnt].fro=tai[x];
     37     tai[x]=cnt;
     38     mp[cnt].v=z;
     39 }
     40 inline void bse(int x,int y,int z){
     41     be(x,y,z);
     42     be(y,x,0);
     43 }
     44 bool bfs(){
     45     int i,x,y;
     46     hd=tl=0;
     47     q[tl++]=s;
     48     memset(d,0,sizeof(d));
     49     d[s]=1;
     50     while(hd!=tl){
     51         x=q[hd++];
     52         for(i=tai[x];i;i=mp[i].fro){
     53             y=mp[i].to;
     54             if(!d[y]&&mp[i].v){
     55                 d[y]=d[x]+1;
     56                 q[tl++]=y;
     57             }
     58         }
     59     }
     60     return d[t];
     61 }
     62 int dfs(int x,int mx){
     63     if(x==t){
     64         return mx;
     65     }
     66     int y;
     67     ll re=0,tmp;
     68     for(int &i=cur[x];i;i=mp[i].fro){
     69         y=mp[i].to;
     70         if(d[y]==d[x]+1&&mp[i].v){
     71             tmp=dfs(y,min(mx,mp[i].v));
     72             re+=tmp;
     73             mx-=tmp;
     74             mp[i].v-=tmp;
     75             mp[i^1].v+=tmp;
     76             if(!mx){
     77                 return re;
     78             }
     79         }
     80     }
     81     if(!re){
     82         d[x]=0;
     83     }
     84     return re;
     85 }
     86 int n,m,a[260][260],k;
     87 bool OK(int x){
     88     int i,j;
     89     s=n+m+1;
     90     t=s+1;
     91     memset(tai,0,sizeof(tai));
     92     cnt=1;
     93     for(i=1;i<=n;i++){
     94         for(j=1;j<=m;j++){
     95             if(a[i][j]<=x){
     96                 bse(i,n+j,1);
     97             }
     98         }
     99     }
    100     for(i=1;i<=n;i++){
    101         bse(s,i,1);
    102     }
    103     for(i=1;i<=m;i++){
    104         bse(n+i,t,1);
    105     }
    106     int flow=0;
    107     while(bfs()){
    108         for(i=1;i<=t;i++){
    109             cur[i]=tai[i];
    110         }
    111         flow+=dfs(s,INF);
    112     }
    113     return flow>=n-k+1;
    114 }
    115 int main(){
    116     int i,j;
    117     scanf("%d%d%d",&n,&m,&k);
    118     for(i=1;i<=n;i++){
    119         for(j=1;j<=m;j++){
    120             scanf("%d",&a[i][j]);
    121         }
    122     }
    123     int l=0,r=INF;
    124     int ans;
    125     while(l<=r){
    126         int mid=l+r>>1;
    127         if(OK(mid)){
    128             ans=mid;
    129             r=mid-1;
    130         }else{
    131             l=mid+1;
    132         }
    133     }
    134     printf("%d
    ",ans);
    135     return 0;
    136 }
    137 
    138 /*
    139 
    140 */
  • 相关阅读:
    个人收集
    30个提高Web程序执行效率的好经验
    如何进行有效的代码检查
    软件测试杂谈
    论dotnet应用程序通用开发方法的弊端
    给Linux增加硬盘的方法
    知识分子的生活态度
    深入认识敏捷开发和面向对象
    使用自定义主题让Windows Live Writer在本地预览语法高亮效果
    软件工程项目中数据库的作用以及敏捷开发
  • 原文地址:https://www.cnblogs.com/fengzhiyuan/p/8531003.html
Copyright © 2011-2022 走看看