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


     染色法判定二分图

    输入样例:

    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;
    }

  • 相关阅读:
    Android 内存溢出解决方案(OOM) 整理总结
    浅思OC的语言特性
    netsh winsock reset 11003
    Utility
    百度地图手机四角坐标
    Mysql 导入 MSSQL
    Python import 指定目录中的模块
    POJ:3061-Subsequence(尺取法模板详解)
    POJ:3616-Milking Time
    POJ:2385-Apple Catching(dp经典题)
  • 原文地址:https://www.cnblogs.com/Knight02/p/15799042.html
Copyright © 2020-2023  润新知