[SCOI2015]小凸玩矩阵
[SCOI2015]小凸玩矩阵
链接:https://www.luogu.com.cn/problem/P4251
题解:可以发现去掉了\(k\)的限制之后,原问题是一个二分图的最大独立集的问题,加上了\(k\)的限制就可以直接二分,但要注意的是求第\(k\)大的,所以要转化为求第\(n-k+1\)小的。
#include<iostream>
using namespace std;
struct node
{
int v,data,nxt;
};
node edge[100001];
int n,m,head[100001],matched[100001],len,k,ans;
bool used[100001];
void add(int x,int y,int z)
{
edge[++len].v=y;
edge[len].data=z;
edge[len].nxt=head[x];
head[x]=len;
return;
}
bool dfs(int x,int L)
{
for (int i=head[x];i>0;i=edge[i].nxt)
if (!used[edge[i].v]&&edge[i].data<=L)
{
used[edge[i].v]=1;
if (matched[edge[i].v]==0||dfs(matched[edge[i].v],L))
{
matched[edge[i].v]=x;
return 1;
}
}
return 0;
}
bool check(int L)
{
ans=0;
for (int i=1;i<=m;++i)
matched[i]=0;
for (int i=1;i<=n;++i)
{
for (int j=1;j<=m;++j)
used[j]=0;
ans+=dfs(i,L);
}
return ans>=k;
}
int main()
{
int d,res=1e9;
cin>>n>>m>>k;
k=n+1-k;
for (int i=1;i<=n;++i)
for (int j=1;j<=m;++j)
{
cin>>d;
add(i,j,d);
}
int first=1,last=1e9,mid;
while (first<=last)
{
mid=(first+last)/2;
if (check(mid))
{
last=mid-1;
res=min(res,mid);
}
else
first=mid+1;
}
cout<<res<<endl;
return 0;
}
本文来自博客园,作者:zhouhuanyi,转载请注明原文链接:https://www.cnblogs.com/zhouhuanyi/p/16983588.html

浙公网安备 33010602011771号