• 染色法判定二分图, 二分图的最大匹配


     染色法判定二分图

    输入样例:

    4 4
    1 3
    1 4
    2 3
    2 4
    

    输出样例:

    Yes

    #include <iostream>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    
    const int N = 1e5+10, M = 2e5+20;
    int n,m;
    int h[N], e[M], ne[M], idx;
    int color[N];
    
    void add(int a, int b)
    {
        e[idx] = b, ne[idx] = h[a], h[a] = idx++;
    }
    
    bool dfs(int u, int k)
    {
        color[u] = k;
        for(int i = h[u]; i != -1; i = ne[i])
        {
            int j = e[i];
            if(!color[j]){
                if(!dfs(j, 3-k)) return false;
            }else if(color[j]==k) return false;
        }
        return true;
    }
    int main()
    {
        cin >> n >> m;
        
        memset(h, -1, sizeof h);
        int a,b;
        while (m -- )
        {
            scanf("%d%d", &a, &b);
            add(a, b), add(b, a);
        }
        bool flag = true;
        for(int i = 1; i <= n; i ++)
        {
            if(!color[i]){
                if(!dfs(i, 1)){
                    flag = false;
                    break;
                }
            }
        }
        if(flag)
            cout << "Yes";
        else
            cout << "No";
        
        return 0;
    }

    二分图的最大匹配

    输入样例:

    2 2 4
    1 1
    1 2
    2 1
    2 2
    

    输出样例:

    2

    左右两部分点之间的连接与邻接表的加边差不多,

    为了求最优的分配方式,

    依次判断左半部分的点,

    当该点与右半部分匹配时, 则直接将其赋给右点对应的match[ ]

    当该点已分配时, 则继续判断此时这个右点所连接的对象是否还有其他选择的余地

    #include<iostream>
    #include<cstring>
    using namespace std;
    
    const int N = 510, M = 1e5+10;
    int n1,n2;
    int h[N], e[M], ne[M], idx;
    int match[N], st[N];//右节点是否匹配
    
    void add(int a, int b)
    {
        e[idx] = b, ne[idx] = h[a], h[a] = idx ++;
    }
    
    int find(int u)
    {
        for(int i = h[u]; i != -1; i = ne[i])
        {
            int j = e[i];
            if(!st[j]){
                st[j] = 1;
                if(!match[j] || find(match[j])){
                    match[j] = u;
                    return 1;
                }
            }
        }
        return 0;
    }
    
    int main()
    {
        int t,a,b;
        cin >> n1 >> n2 >> t;
        
        memset(h, -1, sizeof h);
        while(t--)
        {
            cin >> a >> b;
            add(a, b);
        }
        
        int res = 0;
        for(int i = 1; i <= n1; i ++)
        {
            memset(st, 0, sizeof st);
            if(find(i)) res ++;
        }
        cout << res;
        return 0;
    }

  • 相关阅读:
    C语言寒假大作战01
    C语言I作业12—学期总结
    C语言I博客作业11
    C语言I博客作业10
    浅谈js模块加载方式(初级)
    浅谈.net的后台校验
    api接口访问限制
    系统操作日志表单形式构建
    RedisUtil(未完,持续更新中....)
    定时处理组件---Quartz.net
  • 原文地址:https://www.cnblogs.com/Knight02/p/15799042.html
Copyright © 2020-2023  润新知