• P3355 骑士共存问题


    题目描述

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

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

    输入格式

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

    输出格式

    将计算出的共存骑士数输出

    输入输出样例

    输入 #1
    3 2
    1 1
    3 3
    输出 #1
    5

    黑白染色构图,能攻击到的就连一条inf的边,跑一遍最大流
    #include<bits/stdc++.h>
    #define inf 0x3f3f3f3f
    using namespace std;
    
    const int maxn = 200*201;
    
    int dx[]={-2,-2,-1,1,2,2,1,-1},dy[]={-1,1,2,2,1,-1,-2,-2};
    
    int n,m,head[maxn],size,cur[maxn],dep[maxn],s,t;
    
    bool ok[220][220];
    
    struct edge{
        int v,nex,flow;
    }e[3000010*2];
    
    void adde(int u,int v,int flow){
        e[size].v=v;e[size].nex=head[u];e[size].flow=flow;head[u]=size++;
    }
    
    bool bfs(){
        memset(dep,-1,sizeof(dep));
        dep[s]=0;queue<int> q;
        q.push(s);
        while(!q.empty()){
            int u=q.front();q.pop();
            for(int i=head[u];~i;i=e[i].nex){
                int v=e[i].v;
                if(dep[v]==-1&&e[i].flow){
                    dep[v]=dep[u]+1;
                    q.push(v);
                }
            }
        }
        return dep[t]!=-1;
    }
    
    int dfs(int u,int f){
        if(u==t) return f;
        int used=0;
        for(int& i=cur[u];~i;i=e[i].nex){
            int v=e[i].v;
            if(e[i].flow&&dep[v]==dep[u]+1){
                int d=dfs(v,min(e[i].flow,f-used));
                used+=d;e[i].flow-=d;e[i^1].flow+=d;
                if(used==f) break;
            }
        }
        return used;
    }
    
    int dinic(){
        int res=0;
        while(bfs()){
            for(int i=0;i<=n*n+1;i++) cur[i]=head[i];
            res+=dfs(s,inf); 
        }
        return res;
    }
    
    int main(){
    //    freopen("in.txt","r",stdin);
        s=0;t=n*n+1;
        scanf("%d%d",&n,&m);
        memset(head,-1,sizeof(head));
        for(int i=1;i<=m;i++) {
            int x,y;scanf("%d%d",&x,&y);
            ok[x][y]=1;
        }
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++){
                if(ok[i][j]) continue;
                if((i+j)&1) {
                    adde(s,(i-1)*n+j,1);adde((i-1)*n+j,s,0);
                }else {
                    adde((i-1)*n+j,t,1);adde(t,(i-1)*n+j,0);
                }
            }
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++){
                if(((i+j)&1)==0) continue;//不要写成if((i+j)&1==0)
                for(int k=0;k<=7;k++){
                    int ex=dx[k]+i,ey=dy[k]+j;
                    if(ex>n||ex<1||ey>n||ey<1) continue;
                    if(ok[ex][ey]) continue;
                    adde((i-1)*n+j,(ex-1)*n+ey,inf);adde((ex-1)*n+ey,(i-1)*n+j,0);
                }
            }
        printf("%d",n*n-m-dinic());
    }
  • 相关阅读:
    测试人员在软件开发过程中的任务是什么?
    python关于文件操作
    字符编码
    内置方法
    数据类型的基本使用
    Python的流程控制
    Python与用户相交互
    编程语言的发展史
    计算机的五大组成
    可迭代对象 迭代器对象 生成器对象
  • 原文地址:https://www.cnblogs.com/plysc/p/11444738.html
Copyright © 2020-2023  润新知