首页 > 代码库 > AC日记——[网络流24题]骑士共存 cogs 746

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

746. [网络流24题] 骑士共存

★★☆   输入文件:knight.in   输出文件:knight.out   简单对比
时间限制:1 s   内存限制:128 MB

骑士共存问题

 

«问题描述:

 

在一个n*n个方格的国际象棋棋盘上,马(骑士)可以攻击的棋盘方格如图所示。棋盘

 

上某些方格设置了障碍,骑士不得进入。

技术分享

«编程任务:

 

对于给定的n*n个方格的国际象棋棋盘和障碍标志,计算棋盘上最多可以放置多少个骑

 

士,使得它们彼此互不攻击。

 

«数据输入:

 

由文件knight.in给出输入数据。第一行有2 个正整数n 和m (1<=n<=200, 0<=m<=n*n)<n2),< span="">

 

分别表示棋盘的大小和障碍数。接下来的m 行给出障碍的位置。每行2 个正整数,表示障

 

碍的方格坐标。

 

«结果输出:

 

将计算出的共存骑士数输出到文件knight.out。

 

输入文件示例 输出文件示例

 

knight.in

 

3 2

 

1 1

 

3 3

knight.out

5
思路:
  染色;
  s到黄色连边,流量1;
  红色到t连边,流量1;
  然后黄色周围8个点能跳到的点连边,流量INF;
  上述所有的点都剔除障碍;
来,上代码:
#include <queue>#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;struct EdgeType {    int v,e,f;};struct EdgeType edge[50050*50];const int dx[9]={0,-2,-1,1,2,2,1,-1,-2};const int dy[9]={0,1,2,2,1,-1,-2,-2,-1};int n,m,s=0,t,head[50050],cnt=1,ans,deep[50050];char Cget;bool if_[205][205];inline void in(int &now){    now=0,Cget=getchar();    while(Cget>9||Cget<0) Cget=getchar();    while(Cget>=0&&Cget<=9)    {        now=now*10+Cget-0;        Cget=getchar();    }}inline void edge_add(int u,int v,int w){    edge[++cnt].v=v,edge[cnt].f=w,edge[cnt].e=head[u],head[u]=cnt;    edge[++cnt].v=u,edge[cnt].f=0,edge[cnt].e=head[v],head[v]=cnt;}bool BFS(){    queue<int>que;    for(int i=s;i<=t;i++) deep[i]=-1;    deep[s]=0,que.push(s);    while(!que.empty())    {        int now=que.front();que.pop();        for(int i=head[now];i;i=edge[i].e)        {            if(deep[edge[i].v]<0&&edge[i].f)            {                deep[edge[i].v]=deep[now]+1;                if(edge[i].v==t) return true;                que.push(edge[i].v);            }        }    }    return false;}int flowing(int now,int flow){    if(now==t||flow<=0) return flow;    int oldflow=0;    for(int i=head[now];i;i=edge[i].e)    {        if(edge[i].f<=0||deep[edge[i].v]!=deep[now]+1) continue;        int pos=flowing(edge[i].v,min(flow,edge[i].f));        flow-=pos;        oldflow+=pos;        edge[i].f-=pos;        edge[i^1].f+=pos;        if(flow==0) return oldflow;    }    if(oldflow==0) deep[now]=-1;    return oldflow;}int main(){    freopen("knight.in","r",stdin);    freopen("knight.out","w",stdout);    in(n),in(m);    ans=n*n-m;    t=n*n+1;int x,y;    while(m--)    {        in(x),in(y);        if_[x][y]=true;    }    for(int i=1;i<=n;i++)    {        for(int j=1;j<=n;j++)        {            if(if_[i][j]) continue;            if((i+j)%2==0)            {                edge_add(s,(i-1)*n+j,1);                for(int v=1;v<=8;v++)                {                    if(i+dx[v]>0&&i+dx[v]<=n&&j+dy[v]>0&&j+dy[v]<=n)                    {                        if(!if_[i+dx[v]][j+dy[v]])                        {                            edge_add((i-1)*n+j,(i+dx[v]-1)*n+j+dy[v],0x7ffffff);                        }                    }                }            }            else edge_add((i-1)*n+j,t,1);        }    }    while(BFS()) ans-=flowing(s,0x7ffffff);    cout<<ans;    return 0;}

 

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