网络流24题 洛谷 3355 骑士共存

转换成最小割;

#include <bits/stdc++.h>

using  namespace  std ;

const  int  mx [ 9 ] = { 2 , 2 , -2 , -2 , -1 , 1 , -1 , 1 } ;
const  int  my [ 9 ] = { -1 , 1 , -1 , 1 , 2 , 2 , -2 , -2 } ; 

const  int  N = 100000 + 10 , inf = 1e8 + 7 ;

queue < int >  q ;

int  hh [ N << 2 ] , head [ N << 2 ] , nxt [ N << 2 ] , to [ N << 2 ] , cn = 1 ;
int  flt [ N << 2 ] , dis [ N ] ;
int  src , sink , x , y , n , m ;
bool  vis [ N ] , tag [ 500 ] [ 500 ] ;

int  minx ( int  a , int  b ) {
    return  a > b ? b : a ;
}

void  create ( int  u , int  v , int  f ) {
    cn ++ ;
    to [ cn ] = v ;
    flt [ cn ] = f ;
    nxt [ cn ] = head [ u ] ;
    head [ u ] = cn ;
    cn ++ ;
    to [ cn ] = u ;
    flt [ cn ] = 0 ;
    nxt [ cn ] = head [ v ] ;
    head [ v ] = cn ;
}

bool  bfs ( ) {
    memset ( vis , 0 , sizeof ( vis ) ) ;
    memset ( dis , 0 , sizeof ( dis ) ) ;
    q . push ( src ) ;
    vis [ src ] = 1 ;
    while ( ! q . empty ( ) ) {
        int  tmp = q . front ( ) ;
        q . pop ( ) ;
        for ( int  i = head [ tmp ] ; i ; i = nxt [ i ] ) {
            int  v = to [ i ] ;
            if ( flt [ i ]  &&  ! vis [ v ] ) {
                dis [ v ] = dis [ tmp ] + 1 ;
                q . push ( v ) ;
                vis [ v ] = true ;
            }
        }
    }
    return  vis [ sink ] ;
}
int  dinic ( int  u , int  delta ) {
    if ( u == sink )  return  delta ;
    int  res = 0 , v ;
    for ( int  i = hh [ u ] ; i  &&  delta ; i = nxt [ i ] ) {
        v = to [ i ] ;
        if ( flt [ i ]  &&  dis [ v ] == dis [ u ] + 1 ) {
            int  dd = dinic ( v , minx ( delta , flt [ i ] ) ) ;
            flt [ i ] -= dd ;
            flt [ i ^ 1 ] += dd ;
            res += dd ;
            delta -= dd ;
            hh [ u ] = i ;
        }
    }
    return  res ;
}

int  main ( ) {

    scanf ( "%d%d" , & n , & m ) ;

    src = 0 ; sink = n * n + 1 ; 

    for ( int  i = 1 ; i <= m ; i ++ ) {
        scanf ( "%d%d" , & x , & y ) ;
        tag [ x ] [ y ] = 1 ;
    }

    for ( int  i = 1 ; i <= n ; i ++ )
        for ( int  j = 1 ; j <= n ; j ++ )
        {
            if( tag [ i ] [ j ] )  continue ;
            int  id = ( i - 1 ) * n + j ;
            if( ( i + j ) & 1 )
            {
                create ( src , id , 1 ) ;
                for( int  k = 0 ; k <= 7 ; k ++ )
                {
                    int  t1 = i + mx [ k ] , t2 = j + my [ k ] ;
                    if ( t1 <= 0  ||  t1 > n  ||  t2 <= 0  ||  t2 > n  ||  tag [ t1 ] [ t2 ] ) continue ;
                    create ( id , ( t1 - 1 ) * n + t2 , inf ) ;
                }
            } else create ( id , sink , 1 );
        }

    int  ans = 0 ;

    while ( bfs ( ) ) {
        ans += dinic ( src , inf ) ;
        for ( int  i = 0 ; i <= n * n + 1 ; i ++ )
            hh [ i ] = head [ i ] ;
    }

    printf ( "%d" , n * n - m - ans ) ;

    return  0 ;
}

Ans

原文地址:https://www.cnblogs.com/horsepower2001/p/8970351.html

时间: 2024-10-13 16:11:13

网络流24题 洛谷 3355 骑士共存的相关文章

网络流24题 洛谷 2756 飞行员配对方案

代码风格迥异 -- 1 #include<bits/stdc++.h> 2 3 const int N=1000+5; 4 5 using namespace std; 6 7 int link[N],g[N][N],ansx[N]; 8 int n,m,u,v,ans; 9 bool vis[N]; 10 11 inline void read( int&x ) { 12 int f=1;x=0;char c=getchar(); 13 while(c>'9'||c<'0

网络流24题 洛谷 4014 分配问题

代码风格迥异 -- #include<bits/stdc++.h> const int N=100+10,M=100000+10; using namespace std; queue<int> q; int head[M],dis[M],flt[M],to[M],nxt[M],cn=1; int c[N],pree[N],pred[N],a[N][N]; int maxcost,mincost,src,sink,tmp,n,x; bool vis[N]; void create(

洛谷 P3355 骑士共存问题

题目描述 在一个 n*n个方格的国际象棋棋盘上,马(骑士)可以攻击的棋盘方格如图所示.棋盘上某些方格设置了障碍,骑士不得进入 对于给定的 n*n 个方格的国际象棋棋盘和障碍标志,计算棋盘上最多可以放置多少个骑士,使得它们彼此互不攻击 输入输出格式 输入格式: 第一行有 2 个正整数n 和 m (1<=n<=200, 0<=m<n2),分别表示棋盘的大小和障碍数.接下来的 m 行给出障碍的位置.每行 2 个正整数,表示障碍的方格坐标. 输出格式: 将计算出的共存骑士数输出 输入输出样

洛谷 P3355 骑士共存问题【最小割】

同方格取数问题:https://www.cnblogs.com/lokiii/p/8430720.html 记得把障碍点去掉,不连边也不计入sum #include<iostream> #include<cstdio> #include<queue> #include<cstring> using namespace std; const int N=100005,inf=1e9,dx[]={-2,-1,1,2,2,1,-1,-2},dy[]={-1,-2,

AC日记——[网络流24题]骑士共存 cogs 746

746. [网络流24题] 骑士共存 ★★☆   输入文件:knight.in   输出文件:knight.out   简单对比时间限制:1 s   内存限制:128 MB 骑士共存问题 «问题描述: 在一个n*n个方格的国际象棋棋盘上,马(骑士)可以攻击的棋盘方格如图所示.棋盘 上某些方格设置了障碍,骑士不得进入. «编程任务: 对于给定的n*n个方格的国际象棋棋盘和障碍标志,计算棋盘上最多可以放置多少个骑 士,使得它们彼此互不攻击. «数据输入: 由文件knight.in给出输入数据.第一行

[网络流24题] 骑士共存

746. [网络流24题] 骑士共存 ★★☆   输入文件:knight.in   输出文件:knight.out   简单对比 时间限制:1 s   内存限制:128 MB 骑士共存问题 «问题描述: 在一个n*n个方格的国际象棋棋盘上,马(骑士)可以攻击的棋盘方格如图所示.棋盘 上某些方格设置了障碍,骑士不得进入. «编程任务: 对于给定的n*n个方格的国际象棋棋盘和障碍标志,计算棋盘上最多可以放置多少个骑 士,使得它们彼此互不攻击. «数据输入: 由文件knight.in给出输入数据.第一

【网络流24题】骑士共存问题(最大流)

[网络流24题]骑士共存问题(最大流) 题面 Cogs 题解 这题本质上和方格取数问题没有任何区别 首先也是可以黑白染色 因为马必定会跳到异色点上面去 然后同样的,源点向一种颜色,另一种颜色向汇点连边 因为代价就是1,所以容量都是1 这里考虑的"相邻"的情况是马的跳法 因此,枚举从当前点能够到达的位置,连一条容量为INF的边过去 障碍直接特殊考虑就行了 最后的答案就是所有可以放的位置数减去最大流(最小割) #include<iostream> #include<cst

[洛谷P3254] [网络流24题] 圆桌游戏

Description 假设有来自m 个不同单位的代表参加一次国际会议.每个单位的代表数分别为ri (i =1,2,--,m). 会议餐厅共有n 张餐桌,每张餐桌可容纳ci (i =1,2,--,n)个代表就餐. 为了使代表们充分交流,希望从同一个单位来的代表不在同一个餐桌就餐.试设计一个算法,给出满足要求的代表就餐方案. 对于给定的代表数和餐桌数以及餐桌容量,编程计算满足要求的代表就餐方案. Input 第1 行有2 个正整数m 和n,m 表示单位数,n 表示餐桌数,1<=m<=150, 1

14. [网络流24题] 搭配飞行员

14. [网络流24题] 搭配飞行员 ★★☆   输入文件:flyer.in   输出文件:flyer.out   简单对比 时间限制:1 s   内存限制:128 MB [问题描述] 飞行大队有若干个来自各地的驾驶员,专门驾驶一种型号的飞机,这种飞机每架有两个驾驶员,需一个正驾驶员和一个副驾驶员.由于种种原因,例如相互配合的问题,有些驾驶员不能在同一架飞机上飞行,问如何搭配驾驶员才能使出航的飞机最多. 如图,假设有10个驾驶员,如图中的V1,V2,…,V10就代表达10个驾驶员,其中V1,V2