题面及提交检测
思路
最小可相交路径覆盖问题->介绍
- Floyd构图(二分图)。
- 匈牙利算法计算最大匹配数。
- 最小路径覆盖=原图的结点数-新图的最大匹配数
code
package 第十届决赛;
import java.util.Arrays;
import java.util.Scanner;
public class 估计人数 {
static int[][] map;//地图
static boolean[][] con;//关系图
static int[] boy;//匹配点
static boolean[] vis;
static int n;
static int m;
static int sum = 1;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
m = sc.nextInt();
map = new int[n][n];
//写入图
for (int i = 0; i < n; i++) {
String str = sc.next();
for (int j = 0; j < m; j++) {
if (str.charAt(j) == '1')
map[i][j] = sum++;
}
}
con=new boolean[sum][sum];
boy=new int[sum];
vis=new boolean[sum];
//初始化关系图
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (map[i][j]>0&&i+1<n&&map[i+1][j]>0)
con[map[i][j]][map[i+1][j]]=true;
if (map[i][j]>0&&j+1<m&&map[i][j+1]>0)
con[map[i][j]][map[i][j+1]]=true;
}
}
//Floyd
for (int i = 1; i < sum; i++) {
for (int j = 1; j < sum; j++) {
for (int k = 1; k < sum; k++) {
if(con[j][i]&&con[i][k]&&j!=k)
con[j][k]=true;
}
}
}
//匈牙利算法
int num=0;
for (int i = 1; i < sum; i++) {
Arrays.fill(vis, true);
if(dfs(i))
num++;
}
System.out.println(sum-num-1);
}
static boolean dfs(int x) {
for (int i = 1; i < sum; i++) {
if(con[x][i]&&vis[i]) {
vis[i]=false;
if(boy[i]==0||dfs(boy[i])) {
boy[i]=x;
return true;
}
}
}
return false;
}
}