hrbust 1492 盒子 二分图最大匹配

来源:互联网 发布:编程的小松鼠壁挂炉 编辑:程序博客网 时间:2024/05/22 16:18

                HRBUST 1492 盒子 点击打开链接

中文题意,简洁明了。

大致思路:

果然,二分图构建很不好想,但是想到了,自然就柳暗花明了。

我们这样想,只要匹配到一次,那么一定会有个盒子被装进另一个盒子中,也就意味中有一个盒子不见了,那么我们求出最大匹配数,也就找到最多个““不见得盒子”,用总数减去这些盒子,剩下的就是最少能看见的了。。。

代码:

//匹配成功一次,代表有个盒子被藏到另一个盒子中,等价于这个盒子“不见了”,所以最后用总数减去所有匹配数,剩下的就是能看见的盒子。//匈牙利bfs实现#include<stdio.h>#include<iostream>#include<queue>#include<vector>#include<string.h>using namespace std;int pre[300000],vis[505];int ml[300000],mr[300000];int a[300000];vector<int>V[300000];int MaxMatch(int n){    int ans=0;    memset(vis,0,sizeof(vis));    memset(ml,-1,sizeof(ml));    memset(mr,-1,sizeof(mr));    for(int i=1; i<=n; i++)    {        if(ml[a[i]]==-1)        {            queue<int>Q;            Q.push(a[i]);            pre[a[i]]=-1;            int flag=0;            while(!Q.empty()&&!flag)            {                int v=Q.front();                Q.pop();                for(int j=0; j<V[v].size()&&!flag; j++)                {                    int to=V[v][j];                    if(vis[to]!=a[i])                    {                        vis[to]=a[i];                        Q.push(mr[to]);                        if(mr[to]>=0)                        {                            pre[mr[to]]=v;                        }                        else                        {                            flag=1;                            int d=v;                            int e=to;                            while(d!=-1)                            {                                int temp=ml[d];                                ml[d]=e;                                mr[e]=d;                                e=temp;                                d=pre[d];                            }                        }                    }                }            }            if(flag)ans++;        }    }    return ans;}int main(){    int m,n;    while(~scanf("%d%d",&m,&n))    {        for(int i=0; i<=300000; i++)V[i].clear();        int b;        for(int i=1; i<=n; i++)        {            scanf("%d%d",&a[i],&b);            V[a[i]].push_back(b);        }        int ans=MaxMatch(n);        printf("%d\n",m-ans);    }}


原创粉丝点击