给定一个N行M列的棋盘,已知某些格子禁止放置。
问棋盘上最多能放多少个不能互相攻击的車。
車放在格子里,攻击范围与中国象棋的“車”一致。
输入格式
第一行包含三个整数N,M,T,其中T表示禁止放置的格子的数量。
接下来T行每行包含两个整数x和y,表示位于第x行第y列的格子禁止放置,行列数从1开始。
输出格式
输出一个整数,表示结果。
思路:首先考虑到了一个車,他是控制这一行和一列,也就是说我们可以而且每一行或者是每一列都不会有跟他同行或者是同列的車,这就让我们想起了二分图,我们可以令行是集合A,列是集合B,A和B中的点都没有边相连接,这样我们把坑点去掉然后建图跑一下二分图最大匹配就好了
代码:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
const int ji=200+5;
const int maxn=205*2+10;
int vis[maxn],pre[maxn];
int n,m,k;
int keng[maxn][maxn];
vector<int >G[maxn];
bool DFS(int u)
{
for(int i=0;i<G[u].size();i++)
{
int v=G[u][i];
if(vis[v])continue;
vis[v]=1;
if(pre[v]==0||DFS(pre[v]))
{
pre[v]=u;
return true;
}
}
return false;
}
int main()
{
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=k;i++)
{
int x,y;
scanf("%d%d",&x,&y);
keng[x][n+y]=1;
}
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
if(!keng[i][n+j])
{
G[i].push_back(n+j);
}
int ans=0;
for(int i=1;i<=n;i++)
{
memset(vis,0,sizeof(vis));
if(DFS(i))
ans++;
}
printf("%d\n",ans);
}