AcWing 861. Maximum matching of bipartite graphs (Java)_Hungarian algorithm

Original title link

①. Title

Insert picture description here

②. Thinking

Insert picture description here

  • Matching: In graph theory, a "matching" is a set of edges, in which any two edges have no common vertices.
  • Maximum match: Among all matches in a graph, the match with the most matching edges is called the maximum match of this graph.
  • Perfect match: If all vertices are matching points in a certain match of a graph, then it is a perfect match.
  • Alternate Road: Starting from an unmatched point, the path formed by successively passing through non-matching edges, matching edges, non-matching edges... is called an alternate path.
  • Augmented road: starting from an unmatched point, take the alternate road, if you pass through another unmatched point (the starting point is not counted), then this alternate road is called the augmented road

③. Learning points

匈牙利算法

④. Code implementation

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;

public class Main {
    
    
	static int N=510,M=100010;
	//邻接表存稀疏图
	static int[] h=new int[M];
	static int[] e=new int[M];
	static int[] ne=new int[M];
	static int idx;
	 //match[j]=a,表示女孩j的现有配对男友是a
	static int[] match=new int[N];
	//st[]数组我称为临时预定数组,st[j]=a表示一轮模拟匹配中,女孩j被男孩a预定了
	static boolean[] st=new boolean[N];
	
	//add模板 邻接表
	static void add(int u,int v) {
    
    
		e[idx]=v;
		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; //那x就预定这个女孩了
				 //如果女孩j没有男朋友,或者她原来的男朋友能够预定其它喜欢的女孩。配对成功,更新match
				if(match[j]==0||find(match[j])) {
    
    
					match[j]=u;
					return true;
				}
			}
		}
		 //自己中意的全部都被预定了。配对失败
		return false;
	}
	
	public static void main(String[] args) throws IOException {
    
    
        Arrays.fill(h,-1);
        BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
        String[] arr=in.readLine().split(" ");
        int n1=Integer.parseInt(arr[0]);
        int n2=Integer.parseInt(arr[1]);
        int m=Integer.parseInt(arr[2]);

        while(m-->0){
    
    
            String[] num=in.readLine().split(" ");
            int u=Integer.parseInt(num[0]);
            int v=Integer.parseInt(num[1]);
            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);

	}
}

Insert picture description here

Guess you like

Origin blog.csdn.net/weixin_45480785/article/details/114155989