北大ACM3041——Asteroids~~最小顶点覆盖问题

来源:互联网 发布:网络模特工资怎么算 编辑:程序博客网 时间:2024/06/01 08:01

题目的意思是:在N * N 的网格中,有K 个小行星,一个强大的武器,可以一次消灭一行或者一列的行星,求最少的发射武器的次数将所有行星消灭。

这个就是最小顶点覆盖问题。求解最小顶点覆盖问题很难,然而最大匹配数等于最小顶点覆盖。所以问题转换成最大匹配的求解。


AC代码:

#include <iostream>#include <vector>using namespace std;//输入int N, K;int R[10001], C[10001];int V;                      //顶点数vector<int> G[10001];     //图的邻接表int match[10001];        //匹配的顶点bool used[10001];          //DFS访问标记 void add_edge(int u, int v) //向图中增加一条连续的u和v 的边{G[u].push_back(v);G[v].push_back(u);}bool dfs(int v)  //寻找增广路{used[v] = true;for(int i = 0; i < G[v].size(); i++){int u = G[v][i], w = match[u];if(w < 0 || !used[w] && dfs(w)){match[v] = u;match[u] = v;return true;}}return false;}int matching()         //求解最大匹配数{int res = 0;memset(match, -1, sizeof(match));for(int v = 0; v < V; v++){if(match[v] < 0){memset(used, 0, sizeof(used));if(dfs(v))res++;}}return res;}int main(){while(cin >> N >> K){for(int i = 0; i < K; i++)cin >> R[i] >> C[i];V = N * 2;for(int j = 0; j < K; j++)add_edge(R[j] - 1, N + C[j] - 1);cout << matching() << endl;}return 0;}


0 0