masonpop @ 2023-05-06 21:11:00
这道题我用匈牙利过了,但是 AcWing 上面的那道差不多的题(这个) 没过。这个数据范围更小,但是 WA 在了最后一个点上并且比标答小。所以我这个代码是有什么问题吗?求助。
那道题的代码:
#include <bits/stdc++.h>
using namespace std;
const int maxn=210;
const int maxm=2e5+10;
const int dx[8]={-1,-2,-2,-1,1,2,2,1};
const int dy[8]={-2,-1,1,2,-2,-1,1,2};//马的移动规则
int n,m,t,x,y;
int head[maxm],to[maxm],nxt[maxm],tot;
int ban[maxn][maxn];//禁止放置
inline void add(int x,int y)
{
to[++tot]=y;
nxt[tot]=head[x];
head[x]=tot;
}
int match[maxm],vis[maxm];
inline int black(int x,int y)//是否黑色
{
if((x+y)%2==0)return 1;
return 0;
}
inline int ID(int x,int y)
{
return n*(x-1)+y;
}
inline int valid(int x,int y)
{
if(x>=1 && x<=n && y>=1 && y<=m)return 1;
return 0;
}
inline int find(int x)//匈牙利算法
{
for(int i=head[x];i;i=nxt[i])
{
int y=to[i];
if(vis[y])continue;
vis[y]=1;
if(!match[y] || find(match[y]))
{
match[y]=x;
return 1;
}
}
return 0;
}
int main()
{
scanf("%d%d%d",&n,&m,&t);
for(int i=1;i<=t;i++)
{
scanf("%d%d",&x,&y);
ban[x][y]=1;
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(!black(i,j) || ban[i][j])continue;
for(int k=0;k<8;k++)
{
int nx=i+dx[k],ny=j+dy[k];
if(valid(nx,ny) && !ban[nx][ny])add(ID(i,j),ID(nx,ny));
}
}
}
int ans=0;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(ban[i][j] || !black(i,j))continue;
memset(vis,0,sizeof(vis));
ans+=find(ID(i,j));
}
}
printf("%d\n",n*m-t-ans);
return 0;
}
by liangbowen @ 2023-05-06 22:06:53
这不是一眼就能看到吗,ID打错了,是*m
(
by masonpop @ 2023-05-07 09:10:13
@liangbowen 好吧,我是弱智。不过还是挺感谢的。
此贴结。