网络流24题之二十四 骑士共存 最大独立集
来源:互联网 发布:简繁体转换软件 编辑:程序博客网 时间:2024/05/07 18:10
问题描述:
在一个 n*n 个方格的国际象棋棋盘上,马(骑士)可以攻击的棋盘方格如图所示。棋盘
上某些方格设置了障碍,骑士不得进入。
编程任务:
对于给定的 n*n 个方格的国际象棋棋盘和障碍标志, 计算棋盘上最多可以放置多少个骑
士,使得它们彼此互不攻击。
数据输入:
由文件 input.txt 给出输入数据。第一行有 2 个正整数 n 和 m (1<=n<=200, 0<=m<n 2 ),
分别表示棋盘的大小和障碍数。接下来的 m 行给出障碍的位置。每行 2 个正整数,表示障
碍的方格坐标。
结果输出:
将计算出的共存骑士数输出到文件 output.txt。
输入文件示例 输出文件示例
input.txt
3 2
1 1
在一个 n*n 个方格的国际象棋棋盘上,马(骑士)可以攻击的棋盘方格如图所示。棋盘
上某些方格设置了障碍,骑士不得进入。
编程任务:
对于给定的 n*n 个方格的国际象棋棋盘和障碍标志, 计算棋盘上最多可以放置多少个骑
士,使得它们彼此互不攻击。
数据输入:
由文件 input.txt 给出输入数据。第一行有 2 个正整数 n 和 m (1<=n<=200, 0<=m<n 2 ),
分别表示棋盘的大小和障碍数。接下来的 m 行给出障碍的位置。每行 2 个正整数,表示障
碍的方格坐标。
结果输出:
将计算出的共存骑士数输出到文件 output.txt。
输入文件示例 输出文件示例
input.txt
3 2
1 1
3 3
output.txt
5
【问题分析】
二分图最大独立集,转化为二分图最大匹配,从而用最大流解决。
【建模方法】
首先把棋盘黑白染色,使相邻格子颜色不同。把所有可用的黑色格子看做二分图X集合中顶点,可用的白色格子看做Y集合顶点。建立附加源S汇T,从S向X集合中每个顶点连接一条容量为1的有向边,从Y集合中每个顶点向T连接一条容量为1的有向边。从每个可用的黑色格子向骑士一步能攻击到的可用的白色格子连接一条容量为无穷大的有向边。求出网络最大流,要求的结果就是可用格子的数量减去最大流量。
代码:
const dx:array[1..8] of longint=(1,1,-1,-1,2,2,-2,-2); dy:array[1..8] of longint=(2,-2,2,-2,1,-1,1,-1);var n,m,x,y,i,j,k,ans,e,s,t:longint; cur,last,d,num,fa:array[0..50000] of longint; a:array[1..200,1..200] of boolean; side:array[1..500000] of record x,y,c,op,next:longint; end;procedure add(x,y,c:longint);begin inc(e); side[e].x:=x; side[e].y:=y; side[e].c:=c; side[e].op:=e+1; side[e].next:=last[x]; last[x]:=e; inc(e); side[e].x:=y; side[e].y:=x; side[e].c:=0; side[e].op:=e-1; side[e].next:=last[y]; last[y]:=e;end;procedure remark(x:longint);var min,i:longint;begin min:=n*n-m+1; cur[x]:=last[x]; i:=cur[x]; while i>0 do with side[i] do begin if (c>0)and(d[y]<min) then min:=d[y]; i:=next; end; d[x]:=min+1;end;procedure change;var min,i:longint;begin min:=maxlongint; i:=t; while i<>s do with side[fa[i]] do begin if c<min then min:=c; i:=x; end; ans:=ans+min; i:=t; while i<>s do with side[fa[i]] do begin dec(c,min); inc(side[op].c,min); i:=x; end;end;procedure sap;var i:longint;begin for i:=s to t do cur[i]:=last[i]; num[0]:=n*n-m+2; i:=s; while d[s]<n*n-m+2 do begin while cur[i]>0 do with side[cur[i]] do if (c>0)and(d[y]+1=d[x]) then break else cur[i]:=next; if cur[i]=0 then begin dec(num[d[i]]); if num[d[i]]=0 then break; remark(i); inc(num[d[i]]); if i<>s then i:=side[fa[i]].x; end else begin fa[side[cur[i]].y]:=cur[i]; i:=side[cur[i]].y; if i=t then begin change; i:=s; end; end; end;end;begin assign(input,'kni.in'); assign(output,'kni.out'); reset(input); rewrite(output); readln(n,m); fillchar(a,sizeof(a),true); for i:=1 to m do begin readln(x,y); a[x,y]:=false; end; s:=0; t:=n*n+1; for i:=1 to n do for j:=1 to n do if (i mod 2=j mod 2)and(a[i,j]) then begin for k:=1 to 8 do begin x:=i+dx[k]; y:=j+dy[k]; if (x<1)or(x>n)or(y<1)or(y>n) then continue; if a[x,y]=false then continue; add((i-1)*n+j,(x-1)*n+y,1); end; add(s,(i-1)*n+j,1); end else if a[i,j] then add((i-1)*n+j,t,1); sap; writeln(n*n-m-ans); close(input); close(output); end.
0 0
- 网络流24题之二十四 骑士共存 最大独立集
- 【网络流二十四题 骑士共存问题】【二分图点权最大独立集->最小割】
- [网络流24题] 24 骑士共存(二分图最大独立集,网络最小割)
- 【COGS】746 [网络流24题] 骑士共存 最大独立集
- Cogs 746. [网络流24题] 骑士共存(最大独立集)
- [网络流24题][codevs1922] 骑士共存问题 二分图最大独立集
- [网络流24题]骑士共存问题 二分图/最大点权独立集
- 网络流二十四题之二十四 —— 骑士共存问题(KNI)
- 线性规划与网络流24题の24 骑士共存问题 (二分图最大独立集)
- loj6226「网络流 24 题」骑士共存问题(二分图最大点独立集,最小割)
- 骑士共存问题[网络流24题之24]
- cogs746 [网络流24题]骑士共存
- 【网络流24题】骑士共存问题
- [网络流24题]骑士共存问题
- 【网络流二十四题 方格取数问题】【二分图点权最大独立集->最小割】
- wikioi 1922 骑士共存问题 最大独立集
- 骑士共存问题 二分图的最大独立集
- NKOJ-1569 骑士共存 <最大独立集><染色法建图>
- 动态编译_DynamicCompile、反射调用main方法问题JAVA214
- 2016腾讯校园招聘模拟考试(2016.03.25)
- 少线索的陌生人信息挖掘
- 深入理解 Java 虚拟机-Java 垃圾收集机制
- leetcode——168——Excel Sheet Column Title
- 网络流24题之二十四 骑士共存 最大独立集
- 使用eclipse+python编写爬虫获取python百科的1000条词条
- JavaScript语言精粹——继承
- 遗传算法在游戏中的应用——y=x^2
- VK Cup 2016 - Round 1 (Div. 2 Edition) B
- 简单的电影介绍应用
- hdu 1176 免费馅饼【DP+详解】
- nyoj20吝啬的国度
- mysql导入/导出CSV文件