zoukankan      html  css  js  c++  java
  • 【Codevs1922&网络流24题】骑士共存问题(最小割)

    题意:

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

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

    n<=200,m<=n^2

    思路:经典的二分图最大独立集,采用黑白点染色的思想。

    如果按照相邻点黑白不同染色,可以发现每次跳到的点必定与现在所在点不同色,二分图最大匹配即可。

    每切断一条黑白点之间的边就是少放了一个骑士,用最小割算出最少要切断几条边,总数减去有障碍的再减切断的边数就是最大匹配数,最大独立集又可以转化为最大匹配数。

    这里用最小割来解决,因为不能允许任何黑白点之间的任何一条边有流量,符合最小割的思想。

      1 const dx:array[1..8]of longint=(-2,-2,-1,-1,1,1,2,2);
      2       dy:array[1..8]of longint=(-1,1,-2,2,-2,2,-1,1);
      3 var head,vet,next,len,fan,gap,dis:array[0..500000]of longint;
      4     b,num,a:array[1..300,1..300]of longint;
      5     n,m,i,tot,x,y,k,j,source,src,s:longint;
      6 
      7 procedure add(a,b,c:longint);
      8 begin
      9  inc(tot);
     10  next[tot]:=head[a];
     11  vet[tot]:=b;
     12  len[tot]:=c;
     13  head[a]:=tot;
     14 end;
     15 
     16 function min(x,y:longint):longint;
     17 begin
     18  if x<y then exit(x);
     19  exit(y);
     20 end;
     21 
     22 function dfs(u,aug:longint):longint;
     23 var e,v,val,flow,t:longint;
     24 begin
     25  if u=src then exit(aug);
     26  flow:=0; val:=s-1;
     27  e:=head[u];
     28  while e<>0 do
     29  begin
     30   v:=vet[e];
     31   if len[e]>0 then
     32   begin
     33    if dis[u]=dis[v]+1 then
     34    begin
     35     t:=dfs(v,min(len[e],aug-flow));
     36     len[e]:=len[e]-t;
     37     len[fan[e]]:=len[fan[e]]+t;
     38     flow:=flow+t;
     39     if dis[source]>=s then exit(flow);
     40     if aug=flow then break;
     41    end;
     42    val:=min(val,dis[v]);
     43   end;
     44   e:=next[e];
     45  end;
     46  if flow=0 then
     47  begin
     48   dec(gap[dis[u]]);
     49   if gap[dis[u]]=0 then dis[source]:=s;
     50   dis[u]:=val+1;
     51   inc(gap[dis[u]]);
     52  end;
     53  exit(flow);
     54 end;
     55 
     56 function maxflow:longint;
     57 var ans:longint;
     58 begin
     59  fillchar(gap,sizeof(gap),0);
     60  fillchar(dis,sizeof(dis),0);
     61  gap[0]:=s; ans:=0;
     62  while dis[source]<s do ans:=ans+dfs(source,maxlongint);
     63  exit(ans);
     64 end;
     65 
     66 begin
     67  assign(input,'codevs1922.in'); reset(input);
     68  assign(output,'codevs1922.out'); rewrite(output);
     69  read(n,m);
     70  for i:=1 to n do
     71   for j:=1 to n do
     72   begin
     73    inc(s); a[i,j]:=(i+j+1) mod 2; num[i,j]:=s;
     74   end;
     75  for i:=1 to m do
     76  begin
     77   read(x,y);
     78   b[x,y]:=1;
     79  end;
     80  s:=n*n+2;
     81  for i:=1 to n do
     82   for j:=1 to n do
     83    if (a[i,j]=1)and(b[i,j]=0) then
     84    begin
     85     for k:=1 to 8 do
     86     begin
     87      x:=i+dx[k]; y:=j+dy[k];
     88      if (x>0)and(x<=n)and(y>0)and(y<=n)and(b[x,y]=0) then
     89      begin
     90       fan[tot+2]:=tot+1;
     91       fan[tot+1]:=tot+2;
     92       add(num[i,j],num[x,y],1);
     93       add(num[x,y],num[i,j],0);
     94      end;
     95     end;
     96    end;
     97  source:=50000; src:=50001;
     98  for i:=1 to n do
     99   for j:=1 to n do
    100    if a[i,j]=1 then
    101     begin
    102      fan[tot+2]:=tot+1;
    103      fan[tot+1]:=tot+2;
    104      add(source,num[i,j],1);
    105      add(num[i,j],source,0);
    106     end
    107      else if b[i,j]=0 then
    108      begin
    109       fan[tot+2]:=tot+1;
    110       fan[tot+1]:=tot+2;
    111       add(num[i,j],src,1);
    112       add(src,num[i,j],0);
    113      end;
    114  writeln(n*n-m-maxflow);
    115  close(input);
    116  close(output);
    117 end.
  • 相关阅读:
    给大家介绍几个网站学习前端和服务器语言的网站吧,一定有合适你的
    centos用yum安装软件提示:另外一个程序锁定了 yum;等待它退出
    模仿小猎CMS首页功能展示的JS效果
    在centos下安装Node.js 开发环境搭建
    discuz在IIS,apache中分别怎么设置伪静态
    CentOS系统下各文件夹的作用
    centos上网设置
    php微信公众平台开发获取access_token,用CURL出现certificate verify failed错误的解决方法
    12.9 NIO
    12.8 Java 9改进的对象序列化
  • 原文地址:https://www.cnblogs.com/myx12345/p/6184586.html
Copyright © 2011-2022 走看看