BZOJ4443 Scoi2015 小凸玩矩陣

2022-05-03 23:12:25 字數 1721 閱讀 8426

小凸和小方是好朋友,小方給小凸乙個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#include

#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;

}

view code

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...