码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj2437 [Noi2011]兔兔与蛋蛋

时间:2018-01-25 21:48:30      阅读:159      评论:0      收藏:0      [点我收藏+]

标签:ems   oid   main   style   algo   close   one   log   void   

二分图博弈果然都是一个套路,必经点必胜,非必经点必败,

但是肯定不能没走一步就重新建图判断必胜还是必败,那么我们可以这样:每走一步就把这个点删掉,然后find他原来的匹配,如果找不到,就说明他是必经点,否则就是非必经点。

技术分享图片
 1 #include <cstdio>
 2 #include <cstring>
 3 #include <iostream>
 4 #include <algorithm>
 5 #include <cmath>
 6 #define N 1601
 7 using namespace std;
 8 int e=1,head[N];
 9 struct edge{int v,next;}ed[N*4];
10 void add(int u,int v){ed[e].v=v;ed[e].next=head[u];head[u]=e++;}
11 int pp[N],del[N],id[41][41];
12 bool vis[N],ans[N];
13 bool find(int x){
14     for(int i=head[x];i;i=ed[i].next){
15         int v=ed[i].v;
16         if(del[v]||vis[v])continue;vis[v]=1;
17         if(!pp[v]||find(pp[v])){
18             pp[v]=x;pp[x]=v;
19             return 1;
20         }
21     }return 0;
22 }
23 int a[41][41],be,n,m,T,sx,sy,tot1,tot2,tot;
24 char ch[41];
25 bool check(int i,int j){return ((i+j)&1)^a[i][j]==be;}
26 int f[N],f_cnt;
27 int main(){
28     scanf("%d%d",&n,&m);
29     for(int i=1;i<=n;i++){
30         scanf("%s",ch+1);
31         for(int j=1;j<=m;j++)
32             if(ch[j]==O)a[i][j]=1;
33             else if(ch[j]==X)a[i][j]=0;
34             else sx=i,sy=j;
35     }
36     be=(sx+sy)&1;
37     for(int i=1;i<=n;i++)
38         for(int j=1;j<=m;j++)if(check(i,j))
39             if(a[i][j])id[i][j]=++tot1;
40             else id[i][j]=++tot2;
41     for(int i=1;i<=n;i++)
42         for(int j=1;j<=m;j++)if(check(i,j)&&(!a[i][j]))
43             id[i][j]+=tot1;
44     tot=tot1+tot2;
45     for(int i=1;i<=n;i++)
46         for(int j=1;j<=m;j++)if(id[i][j]){
47             if(id[i+1][j])add(id[i][j],id[i+1][j]);
48             if(id[i][j+1])add(id[i][j],id[i][j+1]);
49             if(id[i-1][j])add(id[i][j],id[i-1][j]);
50             if(id[i][j-1])add(id[i][j],id[i][j-1]);
51         }
52     for(int i=1;i<=tot1;i++){
53         memset(vis,0,sizeof vis);
54         find(i);
55     }
56     scanf("%d",&T);T<<=1;
57     for(int i=1,x,y;i<=T;i++){
58         int now=id[sx][sy],p=pp[now];
59         del[now]=1;pp[now]=pp[p]=0;
60         if(!p)ans[i]=0;
61         else{
62             memset(vis,0,sizeof vis);
63             ans[i]=find(p)^1;
64         }
65         scanf("%d%d",&sx,&sy);
66     }
67     for(int i=1;i<=T;i+=2)
68         if(ans[i]&&ans[i+1])f[++f_cnt]=(i+1)>>1;
69     printf("%d\n",f_cnt);
70     for(int i=1;i<=f_cnt;i++)
71         printf("%d\n",f[i]);
72     return 0;
73 }
View Code

 

bzoj2437 [Noi2011]兔兔与蛋蛋

标签:ems   oid   main   style   algo   close   one   log   void   

原文地址:https://www.cnblogs.com/Ren-Ivan/p/8352969.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!