蒟蒻求助

P3355 骑士共存问题

GLZP @ 2019-02-17 14:04:09

求助,最大流都能T

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<string>
#include<queue>
#define in inline
#define re register
using namespace std;int cnt=1;
const int inf=999999;
const int maxm=500010;
queue<int>q;
int n,m,ans;
int book[210][210];
int nx[8]={2,1,2,1,-2,-1,-2,-1};
int ny[8]={1,2,-1,-2,1,2,-1,-2};
int head[210],next[maxm],to[maxm],ww[maxm],fro[maxm];
int dep[210];
in void add(int x,int y,int z)
{
    to[++cnt]=y;
    fro[cnt]=x;
    ww[cnt]=z;
    next[cnt]=head[x];
    head[x]=cnt;

    to[++cnt]=x;
    fro[cnt]=y;
    ww[cnt]=0;
    next[cnt]=head[y];
    head[y]=cnt;
}
in int kk(int x,int y)
{
    return (x-1)*n+y;
}
in bool bfs()
{
    memset(dep,0,sizeof dep);
    q.push(0);
    while(q.empty()==0)
    {
        int u=q.front();q.pop();
        for(re int i=head[u];i;i=next[i])
        {
            int v=to[i];
            if(dep[v]||!ww[i])continue;
            dep[v]=dep[u]+1;
            q.push(v);
        }
    }
    return dep[kk(n+1,n+1)];
}
in int dfs(int u,int flow)
{
    if(u==kk(n+1,n+1)||!flow)return flow;
    int add=0;
    for(re int i=head[u];i;i=next[i])
    {
        int v=to[i];
        if(dep[v]!=dep[u]+1||!ww[i])continue;
        int xdd=dfs(v,min(ww[i],flow-add));
        ww[i]-=xdd;
        ww[i^1]+=xdd;
        add+=xdd;
    }
    return add;
}
in void dinic()
{
    while(bfs())
    {
        ans+=dfs(0,inf);
    }
}
int main()
{
    scanf("%d%d",&n,&m);
    for(re int i=1;i<=m;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        book[x][y]=1;
    }
    for(re int i=1;i<=n;i++)
    {
        for(re int j=1;j<=n;j++)
        {
            if(book[i][j]==1)continue;
            if((i+j)&1)
            {
                add(0,kk(i,j),1);
                for(re int k=0;k<8;k++)
                {
                    int tx=i+nx[k];
                    int ty=j+ny[k];
                    if(book[tx][ty]==1||tx>n||tx<1||ty>n||ty<1)continue;
                    add(kk(i,j),kk(tx,ty),inf);

                }
            }
            else add(kk(i,j),kk(n+1,n+1),1);
        }
    }
    dinic();
    printf("%d",n*n-ans-m);
    return 0;
}

|