二分图

问题来源:Problem - 2063

二分图_第1张图片

思路分析:

    这道题用到的算法是匈牙利算法,匈牙利算法的目的就是求二分图最大匹配的算法。

    这位老哥写的匈牙利算法就简单易懂:https://blog.csdn.net/sunny_hun/article/details/80627351

   以这道题的分析来说,假设女生集合有A={A1,A2,A3},男生集合有B={B1,B2,B3},存在关系{{A1,B1},{A1,B2},{A1,B3},{A2,B1},{A2,B3},{A3,B1}}。

   从女生的角度出发,A1,A2都选择各自的第一组关系{A1,B1},{A2,B3},接下来看A3,存在B1已经被人选择了的情况,因此,我们返回B1,查看选择B1关系的女生A1是否还有其他关系可以选择,发现A1,存在关系{A1,B2},那么A3就可以选择关系{A3,B1},这样就选出的二分图的最大匹配,3组关系

多组关系也是使用同种方法,依次类推,直至找到最大匹配

实现代码

import java.util.Scanner;

public class Test_2063 {

static int line[][];

static int used[];

static int boy[];

static int k;

static int m;

static int n;

public static void main(String args[]) {

Scanner in = new Scanner(System.in);

while(in.hasNextInt()) {

k = in.nextInt();

if(k == 0)

break;

m = in.nextInt();

n = in.nextInt();

line = new int[505][505];

used = new int[505];

boy = new int[505];

int sum = 0;

while(k-- > 0) {

int a = in.nextInt();

int b = in.nextInt();

line[a][b] = 1;

}

for(int i=1;i<=m;i++) {

for(int j=1;j<=m;j++) {

used[j] = 0; 

}

if(find(i))

sum++;

}

System.out.println(sum);

}

}

public static boolean find(int x) {

for(int j=1;j<=n;j++) {  //扫描每个男生

if(line[x][j] == 1 && used[j] == 0) { 

used[j] = 1;//如果女生x选择了男生j,且男生j还没有被选择,则把男生j标记

if(boy[j] == 0 || find(boy[j])) {

boy[j] = x;//如果男生j没有搭档,那么男生j的匹配就是女生x

return true;

}

}

}

return false;

}

}

你可能感兴趣的:(二分图)