骑士共存问题

在一个 n*n个方格的国际象棋棋盘上,马(骑士)可以攻击的棋盘方格如图所示。棋盘上某些方格设置了障碍,骑士不得进入

对于给定的 n*n 个方格的国际象棋棋盘和障碍标志,计算棋盘上最多可以放置多少个骑士,使得它们彼此互不攻击

输入格式

第一行有 2 个正整数n 和 m (1<=n<=200, 0<=m<n2),分别表示棋盘的大小和障碍数。接下来的 m 行给出障碍的位置。每行 2 个正整数,表示障碍的方格坐标。


棋盘黑白染色,求最大流即最小割

 

对互相攻击的位置加边,流量为1
注意加边位置合法性
#include<bits/stdc++.h>
#define re return
#define inc(i,l,r) for(int i=l;i<=r;++i)

using namespace std;

template<typename T>inline void rd(T&x)
{
    char c;bool f=0;
    while((c=getchar())<'0'||c>'9')if(c=='-')f=1;
    x=c^48;
    while((c=getchar())>='0'&&c<='9')x=x*10+(c^48);
    if(f)x=-x;
} 

const int maxn=40009;
int n,m,k=1,ans,vis[205][205],s,t,inf=2147483647;
int dx[8]={1,1,2,2,-1,-1,-2,-2},dy[8]={2,-2,1,-1,2,-2,1,-1};

int cur[maxn],hd[maxn],dep[maxn];
struct node{
    int to,nt,flow;
}e[6000005];

inline void add(int x,int y,int z)
{
    e[++k].to=y;e[k].nt=hd[x];hd[x]=k;e[k].flow=z;
    e[++k].to=x;e[k].nt=hd[y];hd[y]=k;e[k].flow=0;
} 

inline bool bfs()
{
    inc(i,1,t)dep[i]=0;
    dep[s]=1;
    queue<int>q;
    q.push(s);
    while(!q.empty())
    {
        int u=q.front();
        q.pop();
        for(int i=hd[u];i;i=e[i].nt)
        {
            int v=e[i].to;
            if(!dep[v]&&e[i].flow)
            {
                dep[v]=dep[u]+1;
                if(v==t)re 1;
                q.push(v);
            }
        }
    }
    re 0;
}

inline int dfs(int x,int flow)
{
    if(x==t)re flow;
    int delta=flow;
    for(int &i=cur[x];i;i=e[i].nt)
    {
        int v=e[i].to;
        if(dep[v]==dep[x]+1&&e[i].flow)
        {
            int d=dfs(v,min(delta,e[i].flow));
            e[i^1].flow+=d;
            e[i].flow-=d;
            delta-=d;
            if(!delta)break;
        }
    }
    re flow-delta;
}

int main()
{
//    freopen("in.txt","r",stdin);
    int x,y;
    rd(n),rd(m);
    s=n*n+1,t=s+1;
    inc(i,1,m)
    {
        rd(x),rd(y);
        vis[x][y]=1;
    } 
    
    inc(i,1,n)inc(j,1,n)
    {
        int v=(i-1)*n+j;
        if(vis[i][j])continue;
        if((i+j)%2)
        {
            add(s,v,1);
            inc(k,0,7)
            {
                int nx=dx[k]+i,ny=dy[k]+j;
                if(nx<1||ny<1||nx>n||ny>n)continue;
                if(vis[nx][ny])continue;
                else add(v,(nx-1)*n+ny,inf);
            }
        }    
        else 
        {
            add(v,t,1);
            inc(k,0,7)
            {
                int nx=dx[k]+i,ny=dy[k]+j;
                if(nx<1||ny<1||nx>n||ny>n)continue;
                if(vis[nx][ny])continue;
                else add((nx-1)*n+ny,v,1);
            }
        }
    }
    
    while(bfs())
    {
        inc(i,1,t)cur[i]=hd[i];
        ans+=dfs(s,inf);
    }
    
    printf("%d",n*n-m-ans);
    re 0;
} 

 

posted @ 2019-08-15 21:34  凉如水  阅读(170)  评论(0编辑  收藏  举报