POJ 3041 简单二分图匹配
题意:
格子上知道一些固定点的位置
然后每一行,每一列都有一个枪,
行上的枪可以扫射一行
列上的枪可以扫射一列
问最少需要多少枪能覆盖格子上那些点
思路:
最小点覆盖=最大匹配
所以以x轴为一个点集 y轴为另一个点集建图
然后求最大匹配就好..
Tips:
nothing..
Code:
View Code
1 #include <stdio.h> 2 #include <cstring> 3 #define clr(x) memset(x, 0, sizeof(x)) 4 const int INF = 0x1f1f1f1f; 5 bool grid[510][510]; 6 7 struct Edge 8 { 9 int next; 10 int to; 11 }edge[1000000]; 12 int tot; 13 int head[510]; 14 15 void add(int s, int u) 16 { 17 edge[tot].to = u; 18 edge[tot].next = head[s]; 19 head[s] = tot++; 20 } 21 22 int link[510]; 23 int vis[510]; 24 int n, sum; 25 26 int dfs(int x) 27 { 28 for(int i = head[x]; i != -1; i = edge[i].next){ 29 int y = edge[i].to; 30 if(!vis[y]){ 31 vis[y] = true; 32 if(link[y] == 0 || dfs(link[y])){ 33 link[y] = x; 34 return true; 35 } 36 } 37 } 38 return false; 39 } 40 41 void solve() 42 { 43 clr(link); 44 sum = 0; 45 for(int i = 1; i <= n; ++i){ 46 clr(vis); 47 if(dfs(i)) 48 sum++; 49 } 50 } 51 52 53 int main() 54 { 55 int i, j, k; 56 int m, a, b; 57 while(scanf("%d %d", &n, &m) != EOF) 58 { 59 memset(head, -1, sizeof(head)); 60 tot = 0; 61 62 while(m--) { 63 scanf("%d %d", &a, &b); 64 add(a, b); 65 } 66 solve(); 67 printf("%d\n", sum); 68 } 69 return 0; 70 }