bzoj4443 小凸玩矩阵
二分+最大check
1 #include<algorithm> 2 #include<iostream> 3 #include<cstdlib> 4 #include<cstring> 5 #include<cstdio> 6 #include<string> 7 #include<cmath> 8 #include<ctime> 9 #include<queue> 10 #include<stack> 11 #include<map> 12 #include<set> 13 #define rre(i,r,l) for(int i=(r);i>=(l);i--) 14 #define re(i,l,r) for(int i=(l);i<=(r);i++) 15 #define Clear(a,b) memset(a,b,sizeof(a)) 16 #define inout(x) printf("%d",(x)) 17 #define douin(x) scanf("%lf",&x) 18 #define strin(x) scanf("%s",(x)) 19 #define LLin(x) scanf("%lld",&x) 20 #define op operator 21 #define CSC main 22 typedef unsigned long long ULL; 23 typedef const int cint; 24 typedef long long LL; 25 using namespace std; 26 void inin(int &ret) 27 { 28 ret=0;int f=0;char ch=getchar(); 29 while(ch<'0'||ch>'9'){if(ch=='-')f=1;ch=getchar();} 30 while(ch>='0'&&ch<='9')ret*=10,ret+=ch-'0',ch=getchar(); 31 ret=f?-ret:ret; 32 } 33 int n,m,k,a[255][255],Max,s,t,ed; 34 int head[1010],next[200020],zhi[200020],cap[200020]; 35 void add(int a,int b,int c) 36 { 37 next[++ed]=head[a],head[a]=ed,zhi[ed]=b,cap[ed]=c; 38 next[++ed]=head[b],head[b]=ed,zhi[ed]=a,cap[ed]=0; 39 } 40 queue<int>h;int dis[1010]; 41 bool bfs() 42 { 43 Clear(dis,0); 44 dis[s]=1;h.push(s); 45 while(!h.empty()) 46 { 47 int x=h.front();h.pop(); 48 for(int i=head[x];i;i=next[i])if(cap[i]&&!dis[zhi[i]]) 49 dis[zhi[i]]=dis[x]+1,h.push(zhi[i]); 50 } 51 return dis[t]; 52 } 53 int dfs(int x,int Max) 54 { 55 if(!Max||x==t)return Max; 56 int ret=0,temp; 57 for(int i=head[x];i;i=next[i])if(cap[i]&&dis[zhi[i]]==dis[x]+1) 58 { 59 temp=dfs(zhi[i],min(Max,cap[i])); 60 ret+=temp,Max-=temp; 61 cap[i]-=temp,cap[i^1]+=temp; 62 if(!Max)return ret; 63 } 64 if(!ret)dis[x]=-1; 65 return ret; 66 } 67 int dinic() 68 { 69 int ret=0; 70 while(bfs())ret+=dfs(s,2147483647); 71 return ret; 72 } 73 bool check(int x) 74 { 75 Clear(head,0);ed=1; 76 re(i,1,n)re(j,1,m) 77 if(a[i][j]<=x)add(i,j+n,1); 78 re(i,1,n)add(s,i,1); 79 re(i,1,m)add(i+n,t,1); 80 int ret=dinic(); 81 if(ret>=n-k+1)return 1; 82 return 0; 83 } 84 int main() 85 { 86 inin(n),inin(m),inin(k);s=n+m+1,t=s+1; 87 re(i,1,n)re(j,1,m)inin(a[i][j]),Max=max(Max,a[i][j]); 88 int l=0,r=Max,mid,ans; 89 while(l<=r) 90 { 91 mid=(l+r)>>1; 92 if(check(mid))ans=mid,r=mid-1; 93 else l=mid+1; 94 } 95 printf("%d",ans); 96 return 0; 97 }