zoukankan      html  css  js  c++  java
  • NYOJ——239月老的难题(二分图最大匹配)

    月老的难题
    时间限制:1000 ms | 内存限制:65535 KB
    难度:4
    描述
    月老准备给n个女孩与n个男孩牵红线,成就一对对美好的姻缘。

    现在,由于一些原因,部分男孩与女孩可能结成幸福的一家,部分可能不会结成幸福的家庭。

    现在已知哪些男孩与哪些女孩如果结婚的话,可以结成幸福的家庭,月老准备促成尽可能多的幸福家庭,请你帮他找出最多可能促成的幸福家庭数量吧。

    假设男孩们分别编号为1~n,女孩们也分别编号为1~n。

    输入
    第一行是一个整数T,表示测试数据的组数(1<=T<=400)
    每组测试数据的第一行有两个整数n,K,其中男孩的人数与女孩的人数都是n。(n<=500,K<=10 000)
    随后的K行,每行有两个整数i,j表示第i个男孩与第j个女孩有可能结成幸福的家庭。(1<=i,j<=n)
    输出
    对每组测试数据,输出最多可能促成的幸福家庭数量
    样例输入
    1
    3 4
    1 1
    1 3
    2 2
    3 2
    样例输出
    2


    刚学二分图,先拿道水题来试下。
    代码:

    include<iostream>
    #include<algorithm>
    #include<cstdlib>
    #include<sstream>
    #include<cstring>
    #include<cstdio>
    #include<string>
    #include<deque>
    #include<stack>
    #include<cmath>
    #include<queue>
    #include<set>
    #include<map>
    using namespace std;
    #define INF 0x3f3f3f3f
    #define MM(x) memset(x,0,sizeof(x))
    #define MMINF(x) memset(x,INF,sizeof(x))
    typedef long long LL;
    const double PI=acos(-1.0);
    const int N=20010;
    struct info
    {
        int to;
        int pre;
    }E[N];
    int head[N],cnt;
    int match[N],vis[N];
    void init()
    {
        memset(head,-1,sizeof(head));
        cnt=0;
        memset(match,-1,sizeof(match));
    }
    void add(int s,int t)
    {
        E[cnt].to=t;
        E[cnt].pre=head[s];
        head[s]=cnt++;
    }
    int dfs(int u)
    {
        for (int i=head[u]; i!=-1; i=E[i].pre)
        {
            int v=E[i].to;
            if(!vis[v])//没被访问过
            {
                vis[v]=1;//标记访问
                if(match[v]==-1||dfs(match[v]))
                //若没之前被匹配过或之后可以放到增广路里就合法
                {
                    match[v]=u;//路径交换取反
                    match[u]=v;//路径交换取反
                    return 1;//成功找到增广路
                }
            }
        }
        return 0;
    }
    int main(void)
    {
        int tcase,i,a,b,n,k;
        scanf("%d",&tcase);
        while (tcase--)
        {
            init();
            scanf("%d%d",&n,&k);
            for (i=0; i<k; i++)
            {
                scanf("%d%d",&a,&b);
                add(a,b+n);
            }
            int r=0;
            for (i=1; i<=n; i++)
            {
                if(match[i]==-1)
                {
                    MM(vis);
                    if(dfs(i))//这个点出发找到增广路
                        r++;
                }   
            }
            printf("%d
    ",r);
        }
        return 0;
    }
  • 相关阅读:
    深入浅出 JVM ClassLoader
    JVM 线上故障排查基本操作
    深入浅出 JVM GC(3)
    MyBatis 源码分析系列文章合集
    MyBatis 源码分析
    MyBatis 源码分析
    MyBatis 源码分析
    MyBatis 源码分析
    MyBatis 源码分析
    MyBatis 源码分析系列文章导读
  • 原文地址:https://www.cnblogs.com/Blackops/p/5766319.html
Copyright © 2011-2022 走看看