ACM HDOJ 1151 (Air Raid)

来源:互联网 发布:怎样查看淘宝销售数据 编辑:程序博客网 时间:2024/04/28 20:40

题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=1151

思路 DAG图(无回路有向图)的最小路径覆盖数 = 节点数 - 最大匹配数

程序一 匈牙利算法 DFS

import java.util.Arrays;import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner scn = new Scanner(System.in);int casesNumber = Integer.parseInt(scn.next());while (0 <= --casesNumber) {int leftSetNumber = Integer.parseInt(scn.next());int rightSetNumber = leftSetNumber;int edgesNumber = Integer.parseInt(scn.next());Hungary hungary = new Hungary(leftSetNumber, rightSetNumber);for (int i = 0; i < edgesNumber; ++i) {int left = Integer.parseInt(scn.next()) - 1;int right = Integer.parseInt(scn.next()) - 1;hungary.addEdge(left, right);}System.out.println(leftSetNumber - hungary.maxMatch());}scn.close();}}class Hungary {private int leftSetNumber;private int rightSetNumber;private boolean[][] matrix;private int[] leftResult;private int[] rightResult;private boolean[] rightUsed;private boolean searchPath(int left) {for (int right = 0; right < rightSetNumber; ++right) {if (matrix[left][right] && !rightUsed[right]) {rightUsed[right] = true;if (-1 == rightResult[right] || searchPath(rightResult[right])) {rightResult[right] = left;leftResult[left] = right;return true;}}}return false;}public Hungary(int leftSetNumber, int rightSetNumber) {this.leftSetNumber = leftSetNumber;this.rightSetNumber = rightSetNumber;matrix = new boolean[leftSetNumber][rightSetNumber];leftResult = new int[leftSetNumber];rightResult = new int[rightSetNumber];rightUsed = new boolean[rightSetNumber];}public void addEdge(int left, int right) {matrix[left][right] = true;}public int maxMatch() {Arrays.fill(leftResult, -1);Arrays.fill(rightResult, -1);Arrays.fill(rightUsed, false);int count = 0;for (int left = 0; left < leftSetNumber; ++left) {if (-1 == leftResult[left]) {Arrays.fill(rightUsed, false);if (searchPath(left)) {++count;}}}return count;}}

程序二 匈牙利算法 BFS

import java.util.Arrays;import java.util.LinkedList;import java.util.Queue;import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner scn = new Scanner(System.in);int casesNumber = Integer.parseInt(scn.next());while (0 <= --casesNumber) {int leftSetNumber = Integer.parseInt(scn.next());int rightSetNumber = leftSetNumber;int edgesNumber = Integer.parseInt(scn.next());Hungary hungary = new Hungary(leftSetNumber, rightSetNumber);for (int i = 0; i < edgesNumber; ++i) {int left = Integer.parseInt(scn.next()) - 1;int right = Integer.parseInt(scn.next()) - 1;hungary.addEdge(left, right);}System.out.println(leftSetNumber - hungary.maxMatch());}scn.close();}}class Hungary {private int leftSetNumber;private int rightSetNumber;private boolean[][] matrix;private int[] leftResult;private int[] rightResult;private boolean[] rightUsed;private int[] preLeft;public Hungary(int leftSetNumber, int rightSetNumber) {this.leftSetNumber = leftSetNumber;this.rightSetNumber = rightSetNumber;matrix = new boolean[leftSetNumber][rightSetNumber];leftResult = new int[leftSetNumber];rightResult = new int[rightSetNumber];rightUsed = new boolean[rightSetNumber];preLeft = new int[leftSetNumber];}public void addEdge(int left, int right) {matrix[left][right] = true;}public int maxMatch() {Arrays.fill(leftResult, -1);Arrays.fill(rightResult, -1);Arrays.fill(preLeft, -1);int count = 0;for (int i = 0; i < leftSetNumber; ++i) {if (-1 == leftResult[i]) {Queue<Integer> queue = new LinkedList<Integer>();queue.offer(i);boolean hasAP = false;Arrays.fill(rightUsed, false);while (!queue.isEmpty() && !hasAP) {int left = queue.poll();for (int right = 0; right < rightSetNumber && !hasAP; ++right) {if (matrix[left][right] && !rightUsed[right]) {rightUsed[right] = true;queue.offer(rightResult[right]);if (0 <= rightResult[right]) {preLeft[rightResult[right]] = left;} else {hasAP = true;int currentLeft = left;int currentRight = right;while (-1 != currentLeft) {int lastRight = leftResult[currentLeft];leftResult[currentLeft] = currentRight;rightResult[currentRight] = currentLeft;currentLeft = preLeft[currentLeft];currentRight = lastRight;}}}}}if (-1 != leftResult[i]) {++count;}}}return count;}}

程序三 Hopcroft-Carp 算法

import java.util.Arrays;import java.util.LinkedList;import java.util.Queue;import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner scn = new Scanner(System.in);int casesNumber = Integer.parseInt(scn.next());while (0 <= --casesNumber) {int leftSetNumber = Integer.parseInt(scn.next());int rightSetNumber = leftSetNumber;int edgesNumber = Integer.parseInt(scn.next());HopcroftCarp hopcroftCarp = new HopcroftCarp(leftSetNumber,rightSetNumber);for (int i = 0; i < edgesNumber; ++i) {int left = Integer.parseInt(scn.next()) - 1;int right = Integer.parseInt(scn.next()) - 1;hopcroftCarp.addEdge(left, right);}System.out.println(leftSetNumber - hopcroftCarp.maxMatch());}scn.close();}}class HopcroftCarp {private final int INF = Integer.MAX_VALUE / 2;private int leftSetNumber;private int rightSetNumber;private boolean[][] matrix;private int[] leftResult;private int[] rightResult;private boolean[] rightUsed;private int[] leftGradation;private int[] rightGradation;private int gradation;private boolean searchPath() {Arrays.fill(leftGradation, -1);Arrays.fill(rightGradation, -1);gradation = INF;Queue<Integer> queue = new LinkedList<Integer>();for (int left = 0; left < leftSetNumber; ++left) {if (-1 == leftResult[left]) {queue.offer(left);++leftGradation[left];}}while (!queue.isEmpty()) {int left = queue.poll();if (leftGradation[left] > gradation) {break;}for (int right = 0; right < rightSetNumber; ++right) {if (matrix[left][right] && -1 == rightGradation[right]) {rightGradation[right] = leftGradation[left] + 1;if (-1 == rightResult[right]) {gradation = rightGradation[right];} else {leftGradation[rightResult[right]] = rightGradation[right] + 1;queue.offer(rightResult[right]);}}}}return INF != gradation;}private boolean dfs(int left) {for (int right = 0; right < rightSetNumber; right++) {if (!rightUsed[right] && matrix[left][right]&& rightGradation[right] == leftGradation[left] + 1) {rightUsed[right] = true;if (-1 != rightResult[right]&& rightGradation[right] == gradation) {continue;}if (-1 == rightResult[right] || dfs(rightResult[right])) {rightResult[right] = left;leftResult[left] = right;return true;}}}return false;}public HopcroftCarp(int leftSetNumber, int rightSetNumber) {this.leftSetNumber = leftSetNumber;this.rightSetNumber = rightSetNumber;matrix = new boolean[leftSetNumber][rightSetNumber];leftResult = new int[leftSetNumber];rightResult = new int[rightSetNumber];rightUsed = new boolean[rightSetNumber];leftGradation = new int[leftSetNumber];rightGradation = new int[rightSetNumber];gradation = INF;}public void addEdge(int left, int right) {matrix[left][right] = true;}public int maxMatch() {Arrays.fill(leftResult, -1);Arrays.fill(rightResult, -1);int count = 0;while (searchPath()) {Arrays.fill(rightUsed, false);for (int left = 0; left < leftSetNumber; ++left) {if (-1 == leftResult[left] && dfs(left)) {++count;}}}return count;}}

0 0
原创粉丝点击