最大匹配问题---男女匹配问题(算法)

扯淡:

今天期末复习的时候发现一个算法很有意思,就是男女最大分配对象问题,几对男女最多能凑够几对对象。
在这里插入图片描述
根据社会主义核心价值观,我们最好整一夫一妻制,分配一人一对象,我辈义不容辞。

题目分析:

这题有一说一,网上的分析是匈牙利算法,我就此打住不谈,因为我。。也不太理解。要想深刻理解,请移步匈牙利算法的系统学习。
结合网友的分析,我对这道男女分配问题给出我自己的理解。

题目是尽可能多的给男女匹配,说通俗的话就是这么撮合,才能凑合最多的情侣。

在这里插入图片描述
以该图为例,男1和女1和女2互相喜欢,男3又喜欢女1。

最好的撮合结果就是让男1和女2结合,男3和女1结合。这样可以组成两对,如果女1和女1进行结合的话只能凑合成1对

我们在撮合的过程中,有备胎的尽量给没备胎的让对象。这样就人人开心,独乐乐不如众乐乐。

我们可以这样进行解决

  1. 从男1开始,轮流给男生找对象。
  2. 如果某个男生喜欢的对象已经配对完成的话,那么可以让那个配对的男同胞找一找有没有备胎,如果有的话,让已经配对的对象找备胎,把这个对象让给我。

emm,可能听起来有点绕,我就用上面的动图进行演示一下吧。
在这里插入图片描述
下面是宁大的一道相关题。

某大学组织 n 个学生去多家单位实习,如果所有单位总共可以提供 m 个实习岗位,实习生和实习单位经过洽谈后双方自愿进行,校方则希望能够达到实习人数最大化。假设双方彼此只有愿意和不愿意,没有优先程度考虑,试采用合适的二分图结构表示该过程,并设计合理的算法实现二分图的最大匹配,达到实习人数最大化。

和上面异曲同工。

public class MaxMatching {
    
    
    private int n; // 学生数
    private int m; // 实习岗位数
    private boolean[][] graph; // 二分图的邻接矩阵
    private int[] match; // 存储每个学生匹配的实习岗位编号
    private boolean[] visited; // 存储每个学生是否已经被访问过

    public MaxMatching(int n, int m, boolean[][] graph) {
    
    
        this.n = n;
        this.m = m;
        this.graph = graph;
        this.match = new int[m];
        Arrays.fill(match, -1);
        this.visited = new boolean[n];
    }

    public int getMaxMatching() {
    
    
        int count = 0; // 记录匹配的学生数
        for (int i = 0; i < n; i++) {
    
    
            Arrays.fill(visited, false);
            if (find(i)) {
    
    
                count++;
            }
        }
        return count;
    }

    private boolean find(int student) {
    
    
        for (int i = 0; i < m; i++) {
    
    
            if (graph[student][i] && !visited[i]) {
    
    
                visited[i] = true;
                if (match[i] == -1 || find(match[i])) {
    
    
                    match[i] = student;
                    return true;
                }
            }
        }
        return false;
    }

    public static void main(String[] args) {
    
    
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int m = scanner.nextInt();
        boolean[][] graph = new boolean[n][m];
        for (int i = 0; i < n; i++) {
    
    
            for (int j = 0; j < m; j++) {
    
    
                graph[i][j] = scanner.nextInt() == 1;
            }
        }
        MaxMatching maxMatching = new MaxMatching(n, m, graph);
        System.out.println(maxMatching.getMaxMatching());
    }
}

结语:

漫漫算法路,太难了!呜呜呜呜!

猜你喜欢

转载自blog.csdn.net/faker1234546/article/details/131402332
今日推荐