zoukankan      html  css  js  c++  java
  • loj #6226. 「网络流 24 题」骑士共存问题

    #6226. 「网络流 24 题」骑士共存问题

     

    题目描述

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

    233

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

    输入格式

    第一行有两个正整数 n ext{n}n 和 m ext{m}(1≤n≤200,0≤m≤n2−1)( 1 leq n leq 200, 0 leq m leq n^2 - 1 )(1n200,0mn2​​1) 分别表示棋盘的大小和障碍数。

    输出格式

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

    样例

    样例输入

    3 2
    1 1
    3 3

    样例输出

    5

    数据范围与提示

    1≤n≤2001leq nleq 2001n200

    0≤m≤n2−10 leq m leq n^2-10mn2​​1

    /*
        加了当前弧优化和读入优化,快了不少
    */
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<queue>
    #define maxn 40010
    #define INF 1000000000
    int n,m,head[maxn],dis[maxn],num=1,S,T,cur[maxn];
    bool vis[maxn],mark[maxn];
    struct node{int to,pre,v;}e[maxn*50];
    using namespace std;
    int count(int x,int y){return n*(x-1)+y;}
    void Insert(int from,int to,int v){
        e[++num].to=to;e[num].v=v;e[num].pre=head[from];head[from]=num;
        e[++num].to=from;e[num].v=0;e[num].pre=head[to];head[to]=num;
    }
    bool bfs(){
        for(int i=S;i<=T;i++)dis[i]=-1,cur[i]=head[i];
        queue<int>q;
        q.push(S);dis[S]=0;
        while(!q.empty()){
            int now=q.front();q.pop();
            for(int i=head[now];i;i=e[i].pre){
                int to=e[i].to;
                if(e[i].v>0&&dis[to]==-1){
                    dis[to]=dis[now]+1;
                    if(to==T)return 1;
                    q.push(to);
                }
            }
        }
        return dis[T]!=-1;
    }
    int dinic(int x,int flow){
        if(x==T||flow==0){return flow;}
        int rest=flow;
        for(int &i=cur[x];i;i=e[i].pre){
            int to=e[i].to;
            if(dis[to]==dis[x]+1&&e[i].v>0){
                int delta=dinic(to,min(rest,e[i].v));
                e[i].v-=delta;
                e[i^1].v+=delta;
                rest-=delta;
            }
        }
        return flow-=rest;
    }
    bool check(int x,int y){
        if(x<=n&&x>=1&&y<=n&&y>=1&&!mark[count(x,y)])return 1;
        return 0;
    }
    int qread(){
        int i=0,j=1;
        char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')j=-1;ch=getchar();}
        while(ch<='9'&&ch>='0'){i=i*10+ch-'0';ch=getchar();}
        return i*j;
    }
    int main(){
        n=qread();m=qread();
        S=0,T=n*n+1;
        int x,y;
        for(int i=1;i<=m;i++){
            x=qread();y=qread();
            mark[count(x,y)]=1;
        }
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++){
                if(mark[count(i,j)])continue;
                if((i+j)&1){
                    Insert(S,count(i,j),1);
                    if(check(i-1,j-2))Insert(count(i,j),count(i-1,j-2),1);
                    if(check(i-1,j+2))Insert(count(i,j),count(i-1,j+2),1);
                    if(check(i+1,j-2))Insert(count(i,j),count(i+1,j-2),1);
                    if(check(i+1,j+2))Insert(count(i,j),count(i+1,j+2),1);
                    if(check(i-2,j-1))Insert(count(i,j),count(i-2,j-1),1);
                    if(check(i-2,j+1))Insert(count(i,j),count(i-2,j+1),1);
                    if(check(i+2,j-1))Insert(count(i,j),count(i+2,j-1),1);
                    if(check(i+2,j+1))Insert(count(i,j),count(i+2,j+1),1);
                }
                else Insert(count(i,j),T,1);
            }
        }
        int ans=0;
        while(bfs())ans+=dinic(S,INF);
        printf("%d",n*n-ans-m);
    }
  • 相关阅读:
    thymeleaf时间戳转换
    alerttemplate 时间戳转换
    jQuery.Deferred exception: a.indexOf is not a function TypeError: a.indexOf is not a function
    区分数据是对象还是字符串
    eclipse中选取一列快捷键
    图片拉伸不变型
    这里ajax需要改成同步
    idea如何整理代码格式
    20170311-起早床
    20190310-解决头屑
  • 原文地址:https://www.cnblogs.com/thmyl/p/8939760.html
Copyright © 2011-2022 走看看