公告

👇 微信 👇

图片

欢迎私信交流

Skip to content

12-匈牙利算法 ​

算法思想 ​

算法图解 ​

12-匈牙利算法-1746253401030962507.png

算法模板 ​

java
import java.util.*;

public class Main {
    static int N = 510, M = 100010;
    static int n1, n2, m, idx;
    static int[] e = new int[M], ne = new int[M], h = new int[N];
    // match[i]存储右半点集中的 i 号点所匹配的左半点集中的节点的编号
    static int[] match = new int[N];
    // st[i]表示右半点集中的 i 号点,是否被左半点集中的点尝试连接过,无论是否成功
    static boolean[] st = new boolean[N];

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        n1 = in.nextInt();
        n2 = in.nextInt();
        m = in.nextInt();
        Arrays.fill(h, -1);
        
        while(m -- > 0)
        {
            int u = in.nextInt(), v = in.nextInt();
            add(u, v);
        }
        
        // 求最大匹配数,
        // 遍历左半点集中的点,每个点尝试与右半集合中的所有点进行匹配        
        int res = 0;
        for(int i = 1; i <= n1; i ++ )
        {
            Arrays.fill(st, false);
            if(find(i)) res ++ ;
        }
        
        System.out.println(res);
    }
    
    static void add(int u, int x)
    {
        e[idx] = x;
        ne[idx] = h[u];
        h[u] = idx ++ ;
    }
    
    static boolean find(int u)
    {
        for(int i = h[u]; i != -1; i = ne[i])
        {
            int j = e[i];
            if(!st[j])
            {
                st[j] = true;
                
                // 右半点集中的 j 号点尚未匹配成功或者
                // 原来与其匹配的 k = match[j] 号点可以让出 j 号点(可以与其他节点匹配成功)
                if(match[j] == 0 || find(match[j]))
                {
                    match[j] = u;
                    return true; 
                }
            }
        }
        
        return false;
    }
}