POJ 3041 解题报告

来源:互联网 发布:淘宝卖家威胁能报警吗 编辑:程序博客网 时间:2024/06/08 07:13

这道题其实是求最小覆盖点。如果(r, c)处存在一点,则在(左边)r 和 (右边)c之间连一条线。选取r或者c中的任意一点,则“覆盖”这条边。问题是求覆盖掉所有边的最小点集是多少。而最小点集的大小等于二分图最大匹配的数目。

由如上转换后这道题就成了最大二分匹配题目,可以直接用之前1274的代码。

思路见:http://poj.org/showmessage?message_id=164158

最小点集等于最大二分匹配见:http://poj.org/showmessage?message_id=168863

上述定理叫做 konig's theorem: http://en.wikipedia.org/wiki/K%C3%B6nig%27s_theorem_%28graph_theory%29

测试数据见:http://poj.org/showmessage?message_id=343167

thestoryofsnow3041Accepted388K32MSC++2595B

/* ID: thestor1 LANG: C++ TASK: poj3041 */#include <iostream>#include <fstream>#include <cmath>#include <cstdio>#include <cstring>#include <limits>#include <string>#include <vector>#include <list>#include <set>#include <map>#include <queue>#include <stack>#include <algorithm>#include <cassert>using namespace std;// See http://www.geeksforgeeks.org/maximum-bipartite-matching/ for more detailed explanationconst int MAXN = 500;// A DFS based recursive function that returns true if a// matching for vertex u is possiblebool DFS(int u, const bool adjMatrix[][MAXN], const int N, const int M, int match[], bool visited[]){// Try every job one by onefor (int v = 0; v < M; ++v){// If applicant u is interested in job v and v is// not visitedif (adjMatrix[u][v] && !visited[v]){// Mark v as visitedvisited[v] = true;// If job 'v' is not assigned to an applicant OR// previously assigned applicant for job v (which is match[v]) // has an alternate job available.// Since v is marked as visited in the above line, match[v] // in the following recursive call will not get job 'v' againif (match[v] < 0 || DFS(match[v], adjMatrix, N, M, match, visited)){match[v] = u;return true;}}}return false;}// Returns maximum number of matching from N to M// match: An array to keep track of the applicants assigned to jobs. // The value of match[i] is the applicant number// assigned to job i, the value -1 indicates nobody is assigned.int maximumBipartiteMatching(const bool adjMatrix[][MAXN], const int N, const int M, int match[], bool visited[]){// Count of jobs assigned to applicantsint mbm = 0;// Initially all jobs are availablememset(match, -1, M * sizeof(int));for (int u = 0; u < N; ++u){// Mark all jobs as not seen for next applicant.memset(visited, false, M * sizeof(bool));// Find if the applicant 'u' can get a jobif (DFS(u, adjMatrix, N, M, match, visited)){mbm++;}}return mbm;}int main(){bool adjMatrix[MAXN][MAXN];int match[MAXN];bool visited[MAXN];int N, K;scanf("%d%d", &N, &K);// initially, there is no intersection pointsfor (int r = 0; r < N; ++r){memset(adjMatrix[r], false, N * sizeof(bool));}for (int i = 0; i < K; ++i){int R, C;scanf("%d%d", &R, &C);adjMatrix[R - 1][C - 1] = true;}printf("%d\n", maximumBipartiteMatching(adjMatrix, N, N, match, visited));return 0;  }


0 0
原创粉丝点击