poj3041 建图+最小顶点覆盖(最大匹配数)
这个题的意思是给你一个N*N的矩阵, 里面有K个星球, 我们可以让武器攻击矩阵的一行或者一列来使得这个星球被击碎, 现在问你最少需要几个这种武器才能把所有的星球击碎, 首先我们可以知道每个武器最多攻击一行一次, 因此最多有2*N个武器, 另外我们可以将武器看成顶点, 星球看成边,连接一副图,求出这个图的最小顶点覆盖数也就是最大匹配数即可, 代码如下:
#include <cstdio> #include <cstring> #include <algorithm> #include <vector> using namespace std; const int maxn = 1000+10; struct Hungarian { int n; //顶点的数量 int match[maxn]; int check[maxn]; vector<int> G[maxn]; void init() { for(int i=0; i<=n; i++) G[i].clear(); } void add_edge(int u, int v) { G[u].push_back(v); G[v].push_back(u); } bool dfs(int u) { for(int i=0; i<G[u].size(); i++) { int v = G[u][i]; if(!check[v]) { check[v] = 1; if(match[v]==-1 || dfs(match[v])) { match[u] = v; match[v] = u; return true; } } } return false; } int hungarian() { int ans = 0; memset(match, -1, sizeof(match)); for(int u=1; u<=n; u++) { if(match[u] == -1) { memset(check, 0, sizeof(check)); if(dfs(u)) ++ans; } } return ans; } }hun; int main() { int N, K; scanf("%d%d", &N, &K); hun.n = 2*N; hun.init(); for(int i=0; i<K; i++) { int u, v; scanf("%d%d", &u, &v); hun.add_edge(u, v+N); } printf("%d\n", hun.hungarian()); return 0; }