码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj4443[Scoi2015]小凸玩矩阵

时间:2018-01-21 19:03:22      阅读:106      评论:0      收藏:0      [点我收藏+]

标签:sample   次数   print   font   www.   href   方案   一个   col   

4443: [Scoi2015]小凸玩矩阵

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 1460  Solved: 685
[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

二分答案转化成判定性问题
K大即n-K+1小
如果对于一个数x,有一种方案使得选出来<=x的数的个数 >n-k+1
满足单调性,所以可以二分答案

接下来怎么考虑使选出来的方案的满足条件
贪心,<=x的数越多越好
每行每列只能选一个数,经典的二分图匹配模型

可以通过离散来使二分的次数减少

 

 1 #include<bits/stdc++.h>
 2 #define N 255 
 3 using namespace std;
 4 int n,m,K,cnt,tot,bl[N*2],vis[N*2],hd[N],a[N][N],b[N*N];
 5 struct edge{int v,next;}e[N*N];
 6 void adde(int u,int v){
 7     e[++tot].v=v;
 8     e[tot].next=hd[u];
 9     hd[u]=tot;
10 }
11 
12 bool dfs(int u){
13     //if(vis[u])return 0;vis[u]=1;
14     for(int i=hd[u];i;i=e[i].next){
15         int v=e[i].v;
16         if(vis[v])continue;vis[v]=1;
17         if(!bl[v]||dfs(bl[v])){
18             bl[v]=u;
19             return 1;
20         }
21     }
22     return 0;
23 }
24 
25 inline bool check(int x){
26     tot=0;memset(hd,0,sizeof(hd));
27     memset(bl,0,sizeof(bl));
28     for(int i=1;i<=n;i++)
29     for(int j=1;j<=m;j++)
30     if(a[i][j]<=x)adde(i,j+n);
31     int ret=0;
32     for(int i=1;i<=n;i++){
33         memset(vis,0,sizeof(vis));
34         if(dfs(i))ret++;
35     }
36     return ret>=K;
37 }
38 
39 int main(){
40     scanf("%d%d%d",&n,&m,&K);K=n-K+1;
41     for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)
42     scanf("%d",&a[i][j]),b[++cnt]=a[i][j];
43     sort(b+1,b+1+cnt);
44     int len=unique(b+1,b+1+cnt)-b-1;
45     for(int i=1;i<=n;i++)
46     for(int j=1;j<=m;j++)
47     a[i][j]=lower_bound(b+1,b+1+len,a[i][j])-b;
48     int l=1,r=len,mid,ans;
49     while(l<=r){
50         mid=(l+r)>>1;
51         if(check(mid))r=(ans=mid)-1;
52         else l=mid+1;
53     }
54     printf("%d\n",b[ans]);
55     return 0;
56 }

 

bzoj4443[Scoi2015]小凸玩矩阵

标签:sample   次数   print   font   www.   href   方案   一个   col   

原文地址:https://www.cnblogs.com/wsy01/p/8324728.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!