zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    Vim
    一文搞定Samba云服务器配置(阿里云)CentOS8.3
    第四课 婴儿是如何思考的 思维的发展历程
    C++/VS基础篇
    Windows下Qt VS 打包程序 到他人电脑安装运行出现的问题
    第三课 斯金纳
    第二课基础 弗洛伊德
    C++中头文件和实现文件的关系
    字符串 数字 转换
    Ucore lab1实验报告
  • 原文地址:https://www.cnblogs.com/IUUUUUUUskyyy/p/6502124.html
Copyright © 2011-2022 走看看