题目大意:就是车和车之间不能发生攻击.还有一部分位置不可以放置棋子。
解题思路:一行一列只能放一个,那么对于横纵坐标x和y来说一行一列只有一个交点。所以我们就可以根据X坐标与Y坐标把这些点转换为二分图。
对于重要点问题,我们就可以把这个点去掉,涂黑不让他走,然后在进行一次二分匹配,如果发现最大匹配值小了,那么这个就是重要点。
#include<stdio.h> #include<string.h> #include<iostream> #include<algorithm> using namespace std; #define N 110 int maps[N][N], vis[N], used[N], n, m, k, ans, ans0; struct node { int x,y; }a[N*N];///注意k的取值范围,wa了一次; bool Find(int u) { for(int i=1; i<=m; i++) { if(!vis[i] && maps[u][i]) { vis[i] = 1; if(!used[i] || Find(used[i])) { used[i] = u; return true; } } } return false; } int main() { int t = 1, x, y; while(scanf("%d%d%d", &n, &m, &k)!=EOF) { ans = ans0 = 0; memset(used, 0, sizeof(used)); memset(maps, 0, sizeof(maps)); for(int i=1; i<=k; i++) { scanf("%d%d", &x, &y); a[i].x = x; a[i].y = y; maps[x][y] = 1; } for(int i=1; i<=n; i++) { memset(vis, 0, sizeof(vis)); if(Find(i)) ans++; } for(int i=1; i<=k; i++) { int kk=0; memset(used, 0, sizeof(used)); x=a[i].x; y=a[i].y; maps[x][y] = 0; for(int j=1; j<=n; j++) { memset(vis, 0, sizeof(vis)); if(Find(j)) kk++; } if(kk<ans) ans0++; maps[x][y] = 1; } printf("Board %d have %d important blanks for %d chessmen. ", t++, ans0, ans); } return 0; }