DestinHistoire

 

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)    收藏  举报

导航