【BZOJ】1443: [JSOI2009]游戏Game
【算法】博弈论+二分图匹配(最大流)
【题解】方格图黑白染色得到二分图,
二分图博弈:当起点不属于某个最大匹配时,后手必胜。
问题转化为那些点不属于某个最大匹配。
先找到一个最大匹配,非匹配点加入答案。
假设一个匹配点要解放成为非匹配点,则与其匹配的点必须去匹配另一个点。如果另一个点也是匹配点,则其对面又要去找另一个点。
最终得到结论,一个匹配点的解放,必须有一个非匹配点进入最大匹配。
那么从S一侧的非匹配点出发,沿着“非匹配边-匹配边”的路径走,途中经过的S一侧的匹配点都可以被解放出来。
从T一侧的非匹配点出发也做一次,得到答案。
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
const int maxn=,inf=0x3f3f3f3f;
const int dx[]={,-,,,};
const int dy[]={,,,,-};
struct edge{int v,from,flow;}e[maxn*];
int first[maxn],id[][],idx[maxn],idy[maxn],S,T,cnt,tot=,d[maxn],ans[maxn],ansnum,cur[maxn],col[maxn],n,m;
char s[];
bool map[][],vis[maxn];
void insert(int u,int v,int w)
{tot++;e[tot].v=v;e[tot].flow=w;e[tot].from=first[u];first[u]=tot;
tot++;e[tot].v=u;e[tot].flow=;e[tot].from=first[v];first[v]=tot;}
queue<int>q;
bool bfs()
{
memset(d,-,sizeof(d));
q.push(S);d[S]=;
while(!q.empty())
{
int x=q.front();q.pop();
for(int i=first[x];i;i=e[i].from)
if(d[e[i].v]==-&&e[i].flow)
{
d[e[i].v]=d[x]+;
q.push(e[i].v);
}
}
return d[T]!=-;
}
int dinic(int x,int a)
{
if(x==T||a==)return a;
int flow=,f;
for(int& i=cur[x];i;i=e[i].from)
if(d[e[i].v]==d[x]+&&(f=dinic(e[i].v,min(a,e[i].flow))))
{
e[i].flow-=f;
e[i^].flow+=f;
a-=f;
flow+=f;
if(a==)break;
}
return flow;
}
void dfs(int x,int f)
{
vis[x]=;
if(col[x]==f&&x!=S&&x!=T)ans[++ansnum]=x;
for(int i=first[x];i;i=e[i].from)
if(e[i].flow==f&&!vis[e[i].v])dfs(e[i].v,f);
}
int main()
{
scanf("%d%d",&n,&m);
cnt=;
for(int i=;i<=n;i++)
{
scanf("%s",s+);
for(int j=;j<=m;j++)if(s[j]=='.')
{
id[i][j]=++cnt;
idx[cnt]=i;idy[cnt]=j;
map[i][j]=;
}
}
S=;T=++cnt;
for(int i=;i<=n;i++)
{
for(int j=;j<=m;j++)if(map[i][j])
{
if((i+j)&)
{
insert(S,id[i][j],);
for(int k=;k<=;k++)if(map[i+dx[k]][j+dy[k]])
{
insert(id[i][j],id[i+dx[k]][j+dy[k]],);
}
col[id[i][j]]=;
}
else{insert(id[i][j],T,);col[id[i][j]]=;}
}
}
while(bfs())
{
for(int i=;i<=cnt;i++)cur[i]=first[i];
dinic(S,inf);
}
ansnum=;
memset(vis,,sizeof(vis));
dfs(S,);
memset(vis,,sizeof(vis));
dfs(T,);
if(ansnum)
{
printf("WIN\n");
sort(ans+,ans+ansnum+);
for(int i=;i<=ansnum;i++)printf("%d %d\n",idx[ans[i]],idy[ans[i]]);
}
else printf("LOSE\n");
return ;
}
【BZOJ】1443: [JSOI2009]游戏Game的更多相关文章
- BZOJ:1443: [JSOI2009]游戏Game
原题链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1443 反正不看题解我是完全想不出系列…… 先把棋盘黑白染色,也就是同一对角线上颜色相同,使 ...
- BZOJ.1443.[JSOI2009]游戏Game(二分图博弈 匈牙利)
题目链接 \(Description\) 一个\(N*M\)的有障碍的棋盘,先手放置棋子后,从后手开始轮流移动棋子,不能走重复的位置,不能移动的输.求在哪些位置放棋子是先手必胜的. \(Solutio ...
- BZOJ 1443 [JSOI2009]游戏Game ——博弈论
好题. 首先看到棋盘,先黑白染色. 然后就是二分图的经典模型. 考虑最特殊的情况,完美匹配,那么先手必胜, 因为无论如何,先手走匹配边,后手无论走哪条边,总有对应的匹配边. 如果在不在最大匹配中出发, ...
- BZOJ:[JSOI2009]游戏Game【二分图匹配乱搞】
题目大意:n*m的棋盘,其中有些区域是禁区,两个人在棋盘上进行博弈,后手选择棋子的初始位置,然后先后手轮流将棋子往上下左右移动,走过的区域不能再走,问能否有一个位置使得后手必胜 Input 输入数据首 ...
- BZOJ1443: [JSOI2009]游戏Game
如果没有不能走的格子的话,和BZOJ2463一样,直接判断是否能二分图匹配 现在有了一些不能走的格子 黑白染色后求出最大匹配 如果是完备匹配,则无论如何后手都能转移到1*2的另一端,故先手必输 否则的 ...
- JSOI2009 游戏
1443: [JSOI2009]游戏Game Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 557 Solved: 251[Submit][Stat ...
- BZOJ 1444:[JSOI2009]有趣的游戏
BZOJ 1444:[JSOI2009]有趣的游戏 题目链接 首先我们建出Trie图,然后高斯消元. 我们设\(f_i\)表示经过第\(i\)个点的期望次数: \[ f_x=\sum i\cdot p ...
- [BZOJ 2257][JSOI2009]瓶子和燃料 题解(GCD)
[BZOJ 2257][JSOI2009]瓶子和燃料 Description jyy就一直想着尽快回地球,可惜他飞船的燃料不够了. 有一天他又去向火星人要燃料,这次火星人答应了,要jyy用飞船上的瓶子 ...
- 洛谷 P4571 BZOJ 2257 [JSOI2009]瓶子和燃料
bzoj题目链接 上面hint那里是选择第2个瓶子和第3个瓶子 Time limit 10000 ms Memory limit 131072 kB OS Linux Source Jsoi2009 ...
随机推荐
- poj 3352 Road Construction(边双连通分量+缩点)
题目链接:http://poj.org/problem?id=3352 这题和poj 3177 一样,参考http://www.cnblogs.com/frog112111/p/3367039.htm ...
- mysql常用增删改查命令(纯纪录.orm用得基本功都没了。)
更新表数据: update table_name set xxx=xxx where condition; 增加字段: alter table table_name add field type ot ...
- quartz 配置
<bean id="quartzJob" class="com.wistron.swpc.detaillog.common.SwfitFileAnalysis&qu ...
- BZOJ1415[Noi2005]聪聪和可可——记忆化搜索+期望dp
题目描述 输入 数据的第1行为两个整数N和E,以空格分隔,分别表示森林中的景点数和连接相邻景点的路的条数. 第2行包含两个整数C和M,以空格分隔,分别表示初始时聪聪和可可所在的景点的编号. 接下来E行 ...
- ef group 封装
表达式树,传递 group public class Test<T> where T : class { MoviesEntities db = new MoviesEntities(); ...
- day22 os模块
# 主要用于和当前操作系统做对接的时候获取系统参数用的 import os # os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径 # os.chdir("dir ...
- 洛谷P3085 [USACO13OPEN]阴和阳Yin and Yang(点分治,树上差分)
洛谷题目传送门 闲话 偶然翻到一道没有题解的淀粉质,想证明一下自己是真的弱 然而ZSYC(字符串组合)早就切了 然后证明成功了,WA到怀疑人生,只好借着ZSY的代码拍,拍了几万组就出来了... 思路 ...
- Asp.net与office web apps的整合
其实网上有关office web app的整合已经有相关的文章了,典型的是如何整合Office Web Apps至自己开发的系统(一) 和如何整合Office Web Apps至自己开发的系统(二), ...
- SharePoint 2013 首页修改
最近客户要求统一首页的风格,所以对各网站的首页进行了统一的修改. 1. 左边导航菜单修改: 修改的地方: Site Settings –> Look and feel –> Navigat ...
- 洛谷 P2764 最小路径覆盖问题 解题报告
P2764 最小路径覆盖问题 问题描述: 给定有向图\(G=(V,E)\).设\(P\) 是\(G\) 的一个简单路(顶点不相交)的集合.如果\(V\) 中每个顶点恰好在\(P\) 的一条路上,则称\ ...