标签:
http://acm.hdu.edu.cn/showproblem.php?pid=1281
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 3096 Accepted Submission(s): 1827
题目分析:
1.放尽量多的车,则是求最大匹配
将横坐标放入X集合中,纵坐标放在Y集合中构成一个二分图坐标为(x,y)的位置放车,
则x与y之间有一条连线,车不能互相攻击那么没两条线之间就不能有公共的端点,
即转化为求其最大匹配
2.求重要点个数
将所给的能放车的点一个一个删除,之后求最大匹配,如果最大匹配小于没删之前的最大匹配
那么这个点就是一个重要点
#include<stdio.h> #include<string.h> #include<math.h> #include<stdlib.h> #define N 110 using namespace std; int G[N][N], vis[N], used[N]; int n, m, k; struct st { int a, b; } node[N * N]; bool Find(int u) { int i; for(i = 1 ; i <= m ; i++) { if(!vis[i] && G[u][i]) { vis[i] = 1; if(!used[i] || Find(used[i])) { used[i] = u; return true; } } } return false; } int solve() { int num = 0, i; memset(used, 0, sizeof(used)); for(i = 1 ; i <= n ; i++) { memset(vis, 0, sizeof(vis)); if(Find(i)) num++; } return num; } int main() { int i, p = 0; while(~scanf("%d%d%d", &n, &m, &k)) { p++; memset(G, 0, sizeof(G)); for(i = 1 ; i <= k ; i++) { scanf("%d%d", &node[i].a, &node[i].b); G[node[i].a][node[i].b] = 1; } int ans = solve(); int t = 0; for(i = 1 ; i <= k ; i++) { G[node[i].a][node[i].b] = 0; if(ans > solve()) t++; G[node[i].a][node[i].b] = 1; } printf("Board %d have %d important blanks for %d chessmen.\n", p, t, ans); } return 0; }
标签:
原文地址:http://www.cnblogs.com/qq2424260747/p/4722275.html