小凸和小方是好朋友,小方给小凸一个N*M(N<=M)的矩阵A,要求小秃从其中选出N个数,其中任意两个数字不能在同一行或同一列,现小凸想知道选出来的N个数中第K大的数字的最小值是多少。
标签:
1<=K<=N<=M<=250,1<=矩阵元素<=10^9
#include<stdio.h> #include<iostream> #include<algorithm> using namespace std; const int N=255; int n,m,k,i,j,ans,a[N][N],f[N],p[N]; int tot,head[N],Next[N*N],to[N*N]; void add(int x,int y) { tot++; to[tot]=y; Next[tot]=head[x]; head[x]=tot; } int dfs(int x,int T) { int i; for(i=head[x];i!=-1;i=Next[i]) if(p[to[i]]!=T) { int y=to[i]; p[y]=T; if(f[y]==0||dfs(f[y],T)) { f[y]=x; return 1; } } return 0; } int erfen(int l,int r) { if(l>r) return l; int mid=(l+r)>>1,i,j,ans=0; tot=0; for(i=1;i<=n;i++) head[i]=-1; for(i=1;i<=m;i++) p[i]=f[i]=0; for(i=1;i<=n;i++) for(j=1;j<=m;j++) if(a[i][j]<=mid) add(i,j); for(i=1;i<=n;i++) ans+=dfs(i,i); if(ans>=n-k+1) return erfen(l,mid-1);else return erfen(mid+1,r); } int main() { scanf("%d%d%d",&n,&m,&k); for(i=1;i<=n;i++) for(j=1;j<=m;j++) { scanf("%d",&a[i][j]); ans=max(ans,a[i][j]); } cout<<erfen(1,ans); return 0; }
标签:
原文地址:http://www.cnblogs.com/lwq12138/p/5494937.html