bzoj2437: [Noi2011]兔兔与蛋蛋 二分图博弈

来源:互联网 发布:linux 目录占用空间 编辑:程序博客网 时间:2024/05/01 12:33

题目链接:戳这里

2437: [Noi2011]兔兔与蛋蛋

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 788  Solved: 500
[Submit][Status][Discuss]

Description

Input

输入的第一行包含两个正整数 n、m。 
接下来 n行描述初始棋盘。其中第i 行包含 m个字符,每个字符都是大写英文字母"X"、大写英文字母"O"或点号"."之一,分别表示对应的棋盘格中有黑色棋子、有白色棋子和没有棋子。其中点号"."恰好出现一次。 
接下来一行包含一个整数 k(1≤k≤1000) ,表示兔兔和蛋蛋各进行了k次操作。 
接下来 2k行描述一局游戏的过程。其中第 2i – 1行是兔兔的第 i 次操作(编号为i的操作) ,第2i行是蛋蛋的第i次操作。每个操作使用两个整数x,y来描述,表示将第x行第y列中的棋子移进空格中。 
输入保证整个棋盘中只有一个格子没有棋子, 游戏过程中兔兔和蛋蛋的每个操作都是合法的,且最后蛋蛋获胜。

Output

输出文件的第一行包含一个整数r,表示兔兔犯错误的总次数。 
接下来r 行按递增的顺序给出兔兔“犯错误”的操作编号。其中第 i 行包含一个整数ai表示兔兔第i 个犯错误的操作是他在游戏中的第 ai次操作。 
1 ≤n≤ 40, 1 ≤m≤ 40

Sample Input

样例一:
1 6
XO.OXO
1
1 2
1 1
样例二:
3 3
XOX
O.O
XOX
4
2 3
1 3
1 2
1 1
2 1
3 1
3 2
3 3
样例三:
4 4
OOXX
OXXO
OO.O
XXXO
2
3 2
2 2
1 2
1 3

Sample Output

样例一:
1
1
样例二:
0
样例三:
2
1
2

样例1对应图一中的游戏过程
样例2对应图三中的游戏过程

HINT

Source

做完这题感觉重学了一遍二分图...QAQ我还是太菜了。
感觉二分图博弈的基本模型就是两个人轮流操作,谁不能走谁输,并且有一个格子不能走两遍之类的限制条件,最终可以推得二分图的增广轨是一条合法的移动路径。
对于此题,首先可以推得:距离起点曼哈顿距离为偶数的黑格可达,距离起点曼哈顿距离为奇数的白格可达,因为是白方先手,不妨将起点变成黑格,然后对可达的相邻格子连边构造二分图。
显然一条增广轨是一个合法的移动轨迹,接下来就是如何判断必胜必败态了。
如果起点在一定最大匹配中,则一定先手必胜。因为起点一定在奇数边的交错轨中,只要每次都沿着匹配的边走,一定可以赢。
如果起点不是最大匹配的必需点,那么后手必胜。因为第一步走到的点,一定在不包括起点的最大匹配中,那么后手就可以沿着走匹配边获胜。

然后就是如何判断一个点是否是最大匹配的必需点了。

对于一个点,如果将它删去,从其原匹配点出发依旧能找到增广路,则说明不是必需点。

对于每次操作,如果走之前是必胜态,走之后还是必胜态(此时为对手回合),那么说明走错了。

据此判断即可。


代码:
#include<bits/stdc++.h>using namespace std;typedef long long LL;int read(){char c;int sum=0,f=1;c=getchar();while(c<'0' || c>'9'){if(c=='-')f=-1;c=getchar();}while(c>='0' && c<='9'){sum=sum*10+c-'0';c=getchar();}return sum*f;}int n,m;char s[45][45];int head[45*45],cnt;struct Edge{int to,nex;}edge[45*45*4];void add(int u,int v){edge[++cnt].to=v;edge[cnt].nex=head[u];head[u]=cnt;}int a[45][45],sx,sy,tot;int vis[45*45],tot_vis,match[45*45];bool del[45*45];bool dfs(int x){for(int i=head[x];i;i=edge[i].nex){int nex=edge[i].to;if(del[nex]) continue;if(vis[nex]==tot_vis) continue;vis[nex]=tot_vis;if(!match[nex] || dfs(match[nex])){match[nex]=x;match[x]=nex;return true;}}return false;}int q;bool win[45*45];int main(){n=read();m=read();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]=='.'){sx=i;sy=j;s[i][j]='X';break;}}for(int i=1;i<=n;i++)for(int j=1;j<=m;j++){if((s[i][j]=='O'&&(abs(i-sx)+abs(j-sy))%2==1) || (s[i][j]=='X'&&(abs(i-sx)+abs(j-sy))%2==0))        a[i][j]=++tot;}for(int i=1;i<=n;i++)for(int j=1;j<=m;j++){if(a[i][j]){if(a[i-1][j]) add(a[i][j],a[i-1][j]);if(a[i+1][j]) add(a[i][j],a[i+1][j]);if(a[i][j-1]) add(a[i][j],a[i][j-1]);if(a[i][j+1]) add(a[i][j],a[i][j+1]);}}for(int i=1;i<=tot;i++){if(!match[i]){tot_vis++;dfs(i);}}q=read()*2;for(int i=1;i<=q;i++){int u=a[sx][sy];if(match[u]){int v=match[u];match[v]=match[u]=0;del[u]=1;tot_vis++;win[i]=!dfs(v);}else{del[u]=1;win[i]=false;}sx=read();sy=read();}int ans=0;for(int i=1;i<=q;i+=2)if(win[i]&&win[i+1])ans++;printf("%d\n",ans);for(int i=1;i<=q;i+=2)if(win[i]&&win[i+1])printf("%d\n",(i+1)>>1);return 0;}

阅读全文
'); })();
0 0
原创粉丝点击
热门IT博客
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 欢迎台湾小朋友课文 可以让小朋友玩手机吗 56个民族小朋友简笔画 小朋友咳嗽有痰吃什么 幼儿园小朋友自我介绍 4岁小朋友自我介绍台词 祝福小朋友生日快乐 小朋友手拉手简笔画 幼儿小朋友自我介绍 5岁小朋友撒谎怎么办 小盆友是什么意思 小盆友 小孩子不愿上学 儿童霜 儿童t 6岁儿童不爱学习怎么办 儿童胆小怎么办 3岁儿童的教育 儿童启蒙英语下载 儿童 英文 一个两个三个小朋友 力旺弗朗明歌三期 普罗旺世一期 普罗旺世六期 临期末晚 期末自我评价 高一下学期期末总结 期末余额 高一期末总结 王朝霞各地期末试卷精选数学 期末小结 青骄第二课堂期末考试 青骄第二课堂九年级期末答案 美期贷 微粒贷如何手动还款一期 微粒贷如何手动还款 新期贷app下载 碳化木亭 防腐木景观亭 防腐木亭价格 木从念什么