• HDU 2444 The Accomodation of Students(二分图判定+最大匹配)


      这是一个基础的二分图,题意比较好理解,给出n个人,其中有m对互不了解的人,先让我们判断能不能把这n对分成两部分,这就用到的二分图的判断方法了,二分图是没有由奇数条边构成环的图,这里用bfs染色法就可以判断,其次让我们求分在两部分的最大对数,这就是二分图的最大匹配问题,这里数据只有200,所以匈牙利算法求蹭广路径的办法可以解决这个问题,也相对比较容易编写。

    另外一开始我链式前向星的数组开小了,G++居然返回超时,后来换了C++才RE,想到数组越界的问题,不得不说这些编译器真傲娇啊~

    #include<iostream>
    #include<cstring>
    #include<queue>
    #include<cstdio>
    using namespace std;
    struct EDGE
    {
        int to,nxt;
    }edge[50000];
    int head[220],n,m,tot;
    void add_edge(int x,int y)
    {
        edge[tot].to = y;
        edge[tot].nxt = head[x];
        head[x] = tot++;
    }
    int clo[220];
    bool bfs(int id)
    {
        queue<int>que;
        clo[id] = 1;
        while(!que.empty()) que.pop();
        que.push(id);
        while(!que.empty())
        {
            int now = que.front();
            que.pop();
            for(int i = head[now];i != -1;i = edge[i].nxt)
            {
                int go = edge[i].to;
                if(clo[go] == -1)
                {
                    clo[go] = (clo[now] ^ 1);
                    que.push(go);
                }
                else if(clo[go] == clo[now]) return false;
            }
        }
        return true;
    }
    bool is_erfen()
    {
        memset(clo,-1,sizeof(clo));
        bool mark = true;
        for(int i = 1;i <= n;i++)
        {
            if(clo[i] != -1)continue;
            mark = bfs(i);
            if(mark == false) return false;
        }
        return mark;
    }
    int vis[220],link[220];
    bool Find(int x)
    {
        for(int i = head[x];i != -1;i = edge[i].nxt)
        {
            int now = edge[i].to;
            if(vis[now]) continue;
            vis[now] = 1;
            if(link[now] == -1 || Find(link[now]))
            {
                link[now] = x;
                return true;
            }
        }
        return false;
    }
    int match()
    {
        memset(link,-1,sizeof(link));
        int ans = 0;
        for(int i = 1;i <= n;i++)
        {
            memset(vis,0,sizeof(vis));
            if(Find(i))
                ans++;
        }
        return ans / 2;
    }
    int main()
    {
        while(~scanf("%d%d",&n,&m))
        {
            tot = 0;
            memset(head,-1,sizeof(head));
            for(int i = 0;i < m;i++)
            {
                int u,v;
                scanf("%d%d",&u,&v);
                add_edge(u,v);
                add_edge(v,u);
            }
            bool flag = is_erfen();
            if(!flag)
            {
                printf("No
    ");
            }
            else printf("%d
    ",match());
        }
        return 0;
    }
  • 相关阅读:
    [转]GO语言下载、安装、配置
    Go语言标准库
    GPIO与外部中断
    i.MX RT1050 Boot(RT1021通用)
    i.MX RT系列跨界处理器电源时序设计要点
    i.MX RT1050 Memory Management
    Java如何实现定时任务?
    Java如何使用实时流式计算处理?
    音色的秘密:泛音
    用程序计算出钢琴88个键的音高
  • 原文地址:https://www.cnblogs.com/jifahu/p/5479143.html
Copyright © 2020-2023  润新知