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

http://www.cogs.pro/cogs/problem/problem.php?pid=746

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

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

[网络流24题] 骑士共存 (二分图)_#include

3 3

knight.out

#include<cstdio>
#include<queue>
using namespace std;
int n,m,tot=1,ans;
int front[40010],to[4000100],nextt[4000100],cap[4000100];
int dx[8]={-2,-2,-1,1,2,2,1,-1};
int dy[8]={-1,1,2,2,1,-1,-2,-2};
int barrier[201][201];
int lev[40010],cur[40010];
int src,decc;
queue<int>q;
void add(int u,int v,int w)
{
    to[++tot]=v;nextt[tot]=front[u];front[u]=tot;cap[tot]=w;
    to[++tot]=u;nextt[tot]=front[v];front[v]=tot;cap[tot]=0;
}
void insert(int x,int y,int tx,int ty)
{
    add((x-1)*n+y,(tx-1)*n+ty,1);
}
bool bfs()
{
    for(int i=0;i<=decc;i++) {lev[i]=-1;cur[i]=front[i];}
    while(!q.empty()) q.pop();
    q.push(src);lev[src]=0;
    while(!q.empty())
    {
        int now=q.front();q.pop();
        for(int i=front[now];i;i=nextt[i])
        {
            int t=to[i];
            if(cap[i]>0&&lev[t]==-1)
            {
                lev[t]=lev[now]+1;
                q.push(t);
                if(t==decc) return true;
            }
        }
    }
    return false;
}
int dinic(int now,int flow)
{
    if(now==decc) return flow;
    int rest=0,delta;
    for(int & i=cur[now];i;i=nextt[i])
    {
        int t=to[i];
        if(lev[t]>lev[now]&&cap[i]>0)
        {
            delta=dinic(t,min(flow-rest,cap[i]));
            if(delta)
            {
                cap[i]-=delta;cap[i^1]+=delta;
                rest+=delta;if(rest==flow) break;
            }
        }
    }
    if(rest!=flow) lev[now]=-1;
    return rest;
}
int main()
{
    /*freopen("knight.in","r",stdin);
    freopen("knight.out","w",stdout);*/
    scanf("%d%d",&n,&m);
    int x,y;decc=n*n+1;
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d",&x,&y);
        barrier[x][y]=true;
    }
    for(int i=1;i<=n;i++)
     for(int j=1;j<=n;j++)
      if((i+j)%2) add(src,(i-1)*n+j,1);
      else add((i-1)*n+j,decc,1);
    for(int i=1;i<=n;i++)
     for(int j=1;j<=n;j++)
     {
         if(barrier[i][j]) continue;
         if((i+j)%2)
          for(int k=0;k<8;k++)
               if(i+dx[k]>=1&&i+dx[k]<=n&&j+dy[k]>=1&&j+dy[k]<=n&&!barrier[i+dx[k]][j+dy[k]])
                insert(i,j,i+dx[k],j+dy[k]);
     }
    ans=n*n-m;
    while(bfs()) ans-=dinic(src,4000100); 
    printf("%d",ans);
}
作者:xxy
本文版权归作者所有,转载请用链接,请勿原文转载,Thanks♪(・ω・)ノ。