AcWing 861. Correspondance maximale des graphes bipartis (Java) _Algorithme hongrois

Lien du titre original

①. Titre

Insérez la description de l'image ici

②. Penser

Insérez la description de l'image ici

  • Correspondance: Dans la théorie des graphes, une «correspondance» est un ensemble d'arêtes, dans lequel deux arêtes quelconques n'ont pas de sommets communs.
  • Correspondance maximale: parmi toutes les correspondances d'un graphique, la correspondance avec les arêtes les plus correspondantes est appelée correspondance maximale de ce graphique.
  • Correspondance parfaite: si tous les sommets correspondent à des points dans une certaine correspondance d'un graphique, alors c'est une correspondance parfaite.
  • Route alternative: à partir d'un point sans correspondance, le chemin formé en passant successivement par des bords non correspondants, des bords correspondants, des bords non correspondants ... est appelé un chemin alternatif.
  • Route augmentée: à partir d'un point inégalé, prenez la route alternative, si vous passez par un autre point inégalé (le point de départ n'est pas compté), alors cette route alternative s'appelle la route augmentée

③. Points d'apprentissage

匈牙利算法

④. Implémentation du code

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

	}
}

Insérez la description de l'image ici

Je suppose que tu aimes

Origine blog.csdn.net/weixin_45480785/article/details/114155989
conseillé
Classement