【bzoj1443】【JSOI2009】【游戏game】【二分图博弈】
来源:互联网 发布:winbox mac 登录 ros 编辑:程序博客网 时间:2024/05/09 17:54
Description
Input
输入数据首先输入两个整数N,M,表示了迷宫的边长。 接下来N行,每行M个字符,描述了迷宫。
Output
若小AA能够赢得游戏,则输出一行"WIN",然后输出所有可以赢得游戏的起始位置,按行优先顺序输出 每行一个,否则输出一行"LOSE"(不包含引号)。
Sample Input
3 3
.##
...
#.#
.##
...
#.#
Sample Output
WIN
2 3
3 2
2 3
3 2
HINT
对于100%的数据,有1≤n,m≤100。 对于30%的数据,有1≤n,m≤5。
题解:
可以看出来是二分图博弈的模型。
对图黑白染色之后判断先手是否必胜跑一遍匈牙利算法看一下是否存在完备匹配即可。
如果存在一定是先手必败。
对于第二问,我们可以记录一下左边没有匹配的点。
从这些点开始dfs,从左到右走非匹配边,从右向左走匹配边。
这样dfs到的左边的点就是答案。
然后把二分图左右两边倒过来再做一遍即可。
代码:
#include<iostream>#include<cstdio>#include<cstring>#define N 510using namespace std;int t1,t2,pos[N][N],x[4]={1,0,-1,0},y[4]={0,1,0,-1},bl[N*N];int n,m,cnt,point[N*N],next[N*N],num,to[N*N];bool f[N*N],vis[2][N*N],p[N*N];char s[N][N];void add(int x,int y){next[++cnt]=point[x];point[x]=cnt;to[cnt]=y;}bool find(int x){ for (int i=point[x];i;i=next[i]) if (!f[to[i]]){ f[to[i]]=1; if (!bl[to[i]]||find(bl[to[i]])){bl[to[i]]=x;return true;}} return false;}void dfs(int x,bool vis[]){ vis[x]=1; for (int i=point[x];i;i=next[i]) if (!vis[bl[to[i]]])dfs(bl[to[i]],vis);}int main(){ scanf("%d%d",&n,&m); for (int i=1;i<=n;i++) scanf("%s",s[i]+1); for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) if (s[i][j]=='.') pos[i][j]=++(i+j&1?t1:t2); for(int i=1;i<=n;i++) for (int j=1;j<=m;j++) if (s[i][j]=='.'&&(i+j&1)) for (int k=0;k<4;k++){ int px=i+x[k],py=j+y[k]; if (px<=0||py<=0||px>n||py>m||s[px][py]=='#') continue; add(pos[i][j],pos[px][py]); } for (int i=1;i<=t1;i++){ memset(f,0,sizeof(f)); if (find(i)) num++;else p[i]=1; } if (num==t1&&num==t2){printf("LOSE\n");return 0;} for (int i=1;i<=t1;i++) if (p[i]) dfs(i,vis[1]); memset(point,0,sizeof(point)); memset(p,0,sizeof(p)); memset(bl,0,sizeof(bl)); for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) if (s[i][j]=='.'&&((i+j)%2==0)){ for (int k=0;k<4;k++){ int px=i+x[k],py=j+y[k]; if (px<=0||py<=0||px>n||py>m||s[px][py]=='#') continue; add(pos[i][j],pos[px][py]); } } for (int i=1;i<=t2;i++){ memset(f,0,sizeof(f)); if (!find(i)) p[i]=1; } for (int i=1;i<=t2;i++) if (p[i]) dfs(i,vis[0]); printf("WIN\n"); for (int i=1;i<=n;i++) for (int j=1;j<=m;j++){ if ((i+j&1)&&(vis[1][pos[i][j]]))printf("%d %d\n",i,j); if (((i+j)%2==0)&&(vis[0][pos[i][j]])) printf("%d %d\n",i,j); }}
0 0
- 【BZOJ1443】【JSOI2009】游戏Game 二分图+博弈
- 【bzoj1443】【JSOI2009】【游戏game】【二分图博弈】
- 【BZOJ1443】游戏Game(JSOI2009)-二分图最大匹配+博弈
- 【BZOJ1443】游戏Game,博弈+二分图匹配
- [BZOJ1443][JSOI2009]游戏Game
- BZOJ1443: [JSOI2009]游戏Game
- BZOJ 1443 JSOI2009 游戏Game 二分图博弈
- bzoj 1443: [JSOI2009]游戏Game 二分图博弈
- [BZOJ]1443 [JSOI2009]游戏Game 二分图+博弈
- bzoj1443[game] 二分图
- [二分图博弈] BZOJ 1443 [JSOI2009]游戏Game & BZOJ 2437 [Noi2011]兔兔与蛋蛋
- bzoj 1443: [JSOI2009]游戏Game (二分图博弈+网络流)
- 从bzoj2463到bzoj1443和bzoj2437 博弈+二分图匹配
- [JSOI2009]游戏Game 匹配
- BZOJ 1443 JSOI 2009 游戏Game 二分图+博弈
- BZOJ 1443: [JSOI2009]游戏Game
- Chomp game博弈游戏
- Nim Game 博弈游戏
- 什么是操作系统
- 蚂蚁感冒
- doT.js 模板引擎的使用
- Java‘s regular expressions
- 最长公共子序列
- 【bzoj1443】【JSOI2009】【游戏game】【二分图博弈】
- 增删改查
- leetcode 每日一题 328. Odd Even Linked List
- iOS动态添加和获取属性
- ORA-01093: alter database close only permitted with no sessions connected
- Android组件间通讯
- 关于XOR
- MyEclipse快捷键大全
- synchronized与reentrantLock区别