• 匈牙利算法模板


      匈牙利算法可以求解最大匹配数, 其基本思路是不断地寻找增广路, 由于增广路肯定是奇数个边,并且非匹配边比匹配边多一条, 因此找到增广路以后调换匹配边和非匹配边的就可以使匹配边多一条, 不断重复这个过程即可。。模板如下:

    第二次整理:

    struct Hungarian
    {
        int n;    //顶点的数量
        int match[maxn];
        int check[maxn];
        vector<int> G[maxn];
        void init()
        {
            for(int i=0; i<=n; i++) G[i].clear();
        }
        void add_edge(int u, int v)
        {
            G[u].push_back(v);
            G[v].push_back(u);
        }
        bool dfs(int u)
        {
            for(int i=0; i<G[u].size(); i++)
            {
                int v = G[u][i];
                if(!check[v])
                {
                    check[v] = 1;
                    if(match[v]==-1 || dfs(match[v]))
                    {
                        match[u] = v;
                        match[v] = u;
                        return true;
                    }
                }
            }
            return false;
        }
        int hungarian()
        {
            int ans = 0;
            memset(match, -1, sizeof(match));
            for(int u=1; u<=n; u++)
            {
                if(match[u] == -1)
                {
                    memset(check, 0, sizeof(check));
                    if(dfs(u)) ++ans;
                }
            }
            return ans;
        }
    }hun;
    const int maxn = 1000 + 10;
    
    struct Hungarian
    {
        int n;         //顶点的数量
        int match[maxn];
        int check[maxn];
        vector<int> G[maxn];   //点的连接关系
        void Init()
        {
            for(int i=0; i<=n; i++)
                G[i].clear();
        }
        void AddEdge(int u, int v)
        {
            G[u].push_back(v);
            G[v].push_back(u);
        }
        bool dfs(int u)
        {
            for(int i=0; i<G[u].size(); i++)
            {
                int v = G[u][i];
                if(!check[v])    //不在增广路中
                {
                    check[v] = 1;
                    if(match[v]==-1 || dfs(match[v]))
                    {
                        match[u] = v;
                        match[v] = u;
                        return true;
                    }
                }
            }
            return false;    //不存在增广路
        }
        int hungarian()
        {
            int ans = 0;
            memset(match, -1, sizeof(match));
            for(int u=1; u<=n; u++)
            {
                if(match[u] == -1)
                {
                    memset(check, 0, sizeof(check));
                    if(dfs(u))
                        ++ans;
                }
            }
            return ans;
        }
    }hun;

    应用实例:USACO stall4

    /*
        ID: m1500293
        LANG: C++
        PROG: stall4
    */
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <vector>
    
    using namespace std;
    const int maxn = 1000 + 10;
    
    struct Hungarian
    {
        int n;         //顶点的数量
        int match[maxn];
        int check[maxn];
        vector<int> G[maxn];   //点的连接关系
        void Init()
        {
            for(int i=0; i<=n; i++)
                G[i].clear();
        }
        void AddEdge(int u, int v)
        {
            G[u].push_back(v);
            G[v].push_back(u);
        }
        bool dfs(int u)
        {
            for(int i=0; i<G[u].size(); i++)
            {
                int v = G[u][i];
                if(!check[v])    //不在增广路中
                {
                    check[v] = 1;
                    if(match[v]==-1 || dfs(match[v]))
                    {
                        match[u] = v;
                        match[v] = u;
                        return true;
                    }
                }
            }
            return false;    //不存在增广路
        }
        int hungarian()
        {
            int ans = 0;
            memset(match, -1, sizeof(match));
            for(int u=1; u<=n; u++)
            {
                if(match[u] == -1)
                {
                    memset(check, 0, sizeof(check));
                    if(dfs(u))
                        ++ans;
                }
            }
            return ans;
        }
    }hun;
    
    int main()
    {
        freopen("stall4.in", "r", stdin);
        freopen("stall4.out", "w", stdout);
        int N, M;        //N个奶牛 M个围栏
        scanf("%d%d", &N, &M);
        hun.n = N+M;
        hun.Init();
        for(int i=1; i<=N; i++)
        {
            int num;
            scanf("%d", &num);
            while(num--)
            {
                int t;
                scanf("%d", &t);
                hun.AddEdge(i, N+t);
            }
        }
        printf("%d
    ", hun.hungarian());
        return 0;
    }
  • 相关阅读:
    C#设计模式(6)——原型模式(Prototype Pattern)
    C#设计模式(4)——抽象工厂模式
    C#设计模式(3)——工厂方法模式
    C#设计模式(2)——简单工厂模式
    cmd 打 jar 包
    java eclipse 中给args 传递参数
    java 中值传递和引用传递(转)
    java unreachable code不可达代码
    java语言中if语句的用法
    java中 构造器与void
  • 原文地址:https://www.cnblogs.com/xingxing1024/p/5160184.html
Copyright © 2020-2023  润新知