二分+最大check
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cstdio>
#include<string>
#include<cmath>
#include<ctime>
#include<queue>
#include<stack>
#include<map>
#include<set>
#define rre(i,r,l) for(int i=(r);i>=(l);i--)
#define re(i,l,r) for(int i=(l);i<=(r);i++)
#define Clear(a,b) memset(a,b,sizeof(a))
#define inout(x) printf("%d",(x))
#define douin(x) scanf("%lf",&x)
#define strin(x) scanf("%s",(x))
#define LLin(x) scanf("%lld",&x)
#define op operator
#define CSC main
typedef unsigned long long ULL;
typedef const int cint;
typedef long long LL;
using namespace std;
void inin(int &ret)
{
ret=;int f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=;ch=getchar();}
while(ch>=''&&ch<='')ret*=,ret+=ch-'',ch=getchar();
ret=f?-ret:ret;
}
int n,m,k,a[][],Max,s,t,ed;
int head[],next[],zhi[],cap[];
void add(int a,int b,int c)
{
next[++ed]=head[a],head[a]=ed,zhi[ed]=b,cap[ed]=c;
next[++ed]=head[b],head[b]=ed,zhi[ed]=a,cap[ed]=;
}
queue<int>h;int dis[];
bool bfs()
{
Clear(dis,);
dis[s]=;h.push(s);
while(!h.empty())
{
int x=h.front();h.pop();
for(int i=head[x];i;i=next[i])if(cap[i]&&!dis[zhi[i]])
dis[zhi[i]]=dis[x]+,h.push(zhi[i]);
}
return dis[t];
}
int dfs(int x,int Max)
{
if(!Max||x==t)return Max;
int ret=,temp;
for(int i=head[x];i;i=next[i])if(cap[i]&&dis[zhi[i]]==dis[x]+)
{
temp=dfs(zhi[i],min(Max,cap[i]));
ret+=temp,Max-=temp;
cap[i]-=temp,cap[i^]+=temp;
if(!Max)return ret;
}
if(!ret)dis[x]=-;
return ret;
}
int dinic()
{
int ret=;
while(bfs())ret+=dfs(s,);
return ret;
}
bool check(int x)
{
Clear(head,);ed=;
re(i,,n)re(j,,m)
if(a[i][j]<=x)add(i,j+n,);
re(i,,n)add(s,i,);
re(i,,m)add(i+n,t,);
int ret=dinic();
if(ret>=n-k+)return ;
return ;
}
int main()
{
inin(n),inin(m),inin(k);s=n+m+,t=s+;
re(i,,n)re(j,,m)inin(a[i][j]),Max=max(Max,a[i][j]);
int l=,r=Max,mid,ans;
while(l<=r)
{
mid=(l+r)>>;
if(check(mid))ans=mid,r=mid-;
else l=mid+;
}
printf("%d",ans);
return ;
}