小凸和小方是好朋友,小方給小凸乙個n*m(n<=m)的矩陣a,要求小禿從其中選出n個數,其中任意兩個數字不能在同一行或同一列,現小凸想知道選出來的n個數中第k大的數字的最小值是多少。
第一行給出三個整數n,m,k
接下來n行,每行m個數字,用來描述這個矩陣
如題 3 4 2
1 5 6 6
8 3 4 3
6 8 6 3
31<=k<=n<=m<=250,1<=矩陣元素<=10^9
二分答案x,然後「存在方案使得第k大的數<=x」等價於「存在方案選n-k+1個數<=x」。
那麼二分圖匹配即可。
#include#includeview code#include
#include
#include
#include
#define rep(i,s,t) for(int i=s;i<=t;i++)
#define dwn(i,s,t) for(int i=s;i>=t;i--)
#define ren for(int i=first[x];i;i=next[i])
using
namespace
std;
const
int buffersize=1
<<16
;char buffer[buffersize],*head,*tail;
inline
char
getchar()
return *head++;
}inline
intread()
const
int maxn=510
;const
int maxm=200010
;const
int inf=1e9;
struct
isapadj[maxm];int
ms,fch[maxn];
intd[maxn],s[maxn],cur[maxn],gap[maxn],n,top;
void init(int
n)
void addedge(int u,int v,int
w);fch[u]=ms++;
adj[ms]=(tedge);fch[v]=ms++;
return
; }
void
bfs()
} return
; }
int solve(int s,int
t)
for(i=cur[k];i!=-1;i=adj[i].next)
}if(i==-1
) if(--gap[d[k]]==0) break
; d[k]=lim+1;gap[d[k]]++;
if(k!=s) k=adj[s[--top]].x;}}
return
flow;
}}sol;
intn,m,k,val[maxn][maxn];
int check(int
x) int
main()
while(lif(check(mid=l+r>>1)) r=mid; else l=mid+1
; printf(
"%d\n
",l);
return0;
}
BZOJ4443 Scoi2015 小凸玩矩陣
二分答案,若x可行,說明能取出n k 1個小於等於x的數 為什麼不是k個呢,因為是k大啊不是k小 判斷的話若 i,j 小於等於x,則第i行向第j列連邊,然後跑最大流看是否大於等於n k 1即可 include include include include include include inclu...
bzoj4443 Scoi2015 小凸玩矩陣
小凸和小方是好朋友,小方給小凸乙個n m n m 的矩陣a,要求小禿從其中選出n個數,其中任意兩個數字不能在同一行或同一列,現小凸想知道選出來的n個數中第k大的數字的最小值是多少。1 k n m 250,1 矩陣元素 10 9 來自 第k大可以是第n k 1小,那麼二分答案把不大於mid的點行列連邊...
BZOJ 4443 小凸玩矩陣
題意 中文題 思路 二分答案,然後比較顯然的網路流建圖之後看看最大流是否大於n k 1就可以了 includeusing namespace std define inf 1e9 100 const int maxn 250 250 100 struct edge struct dinic void...