BZOJ-1191 [HNOI2006]超级英雄Hero(二分图最大匹配)
题目描述
主持人总共有 \(m(0<m<1001)\) 道题,选手有 \(n(0<n<1001)\) 种不同的锦囊妙计(编号 \(0\) ~ \(n-1\))。每道题都可以从两种锦囊妙计中选择一种,每种锦囊妙计只能用一次。只有当选手正确回答一道题后,才能进入下一题,否则就被淘汰。一道题使用了它允许的锦囊妙计后,就一定能正确回答,顺利进入下一题。每道题只借助使用锦囊妙计来通过。事先知道了每道题能够使用哪两种锦囊妙计,求怎样选择才能通过最多的题数。
分析
要从问题点出发寻找匹配的锦囊妙计,由于 只有当选手正确回答一道题后,才能进入下一题,否则就被淘汰,所以如果某个问题匹配不到锦囊妙计,则立刻退出。
代码
#include<bits/stdc++.h>
using namespace std;
const int N=2e5+10;
int head[N],num_edge;
struct Edge
{
int to;
int Next;
}edge[N<<1];
int n,m,visit[N],matchx[N],matchy[N];
void add_edge(int from,int to)
{
edge[++num_edge].to=to;
edge[num_edge].Next=head[from];
head[from]=num_edge;
}
bool dfs(int x)
{
for(int i=head[x];i;i=edge[i].Next)
{
int y=edge[i].to;
if(!visit[y])
{
visit[y]=1;
if(!matchy[y]||dfs(matchy[y]))
{
matchy[y]=x;
matchx[x]=y;
return true;
}
}
}
return false;
}
int main()
{
cin>>n>>m;
for(int i=1;i<=m;i++)
{
int x,y;
scanf("%d %d",&x,&y);
add_edge(i,x);
add_edge(i,y);
}
int ans=0;
for(int i=1;i<=m;i++)
{
memset(visit,0,sizeof(visit));
if(dfs(i))
ans++;
else
break;//找不到匹配点立即退出
}
cout<<ans<<endl;
//for(int i=1;i<=ans;i++)
// cout<<matchx[i]<<endl;
return 0;
}
posted on 2020-11-24 23:03 DestinHistoire 阅读(76) 评论(0) 收藏 举报
浙公网安备 33010602011771号