您的位置:首页 > 其它

【BZOJ 2437】 2437: [Noi2011]兔兔与蛋蛋 (博弈+二分图匹配**)

2017-03-30 08:10 399 查看

未经博主同意不得转载

2437: [Noi2011]兔兔与蛋蛋

Time Limit: 10 Sec Memory Limit: 128 MB
Submit: 693 Solved: 442

Description

1 #include<cstdio>
2 #include<cstdlib>
3 #include<cstring>
4 #include<iostream>
5 #include<algorithm>
6 using namespace std;
7 #define Maxn 50
8 #define Maxq 2010
9
10 int n,m;
11
12 struct node
13 {
14     int x,y,next;
15 }t[Maxn*Maxn*4];
16 int first[Maxn*Maxn],len;
17
18 void ins(int x,int y)
19 {
20     t[++len].x=x;t[len].y=y;
21     t[len].next=first[x];first[x]=len;
22 }
23
24 int a[Maxn][Maxn],num[Maxn][Maxn];
25 int tot;
26
27 int match[Maxn*Maxn],chw[Maxn*Maxn];
28 bool vis[Maxn*Maxn];
29
30 bool ffind(int x,int nt)
31 {
32     if(!vis[x]) return 0;
33     for(int i=first[x];i;i=t[i].next) if(chw[t[i].y]!=nt&&vis[t[i].y])
34     {
35         int y=t[i].y;
36         chw[y]=nt;
37         if(!match[y]||ffind(match[y],nt))
38         {
39             match[y]=x;match[x]=y;
40             return 1;
41         }
42     }
43     return 0;
44 }
45
46 int nt,op[Maxn*Maxn];
47 int bx[6]={0,1,0,-1,0},
48     by[6]={0,0,1,0,-1};
49 char s[Maxn];
50
51 bool ret[Maxn*Maxn];
52
53 int nx,ny;
54 void get_ans()
55 {
56     memset(match,0,sizeof(match));
57     memset(chw,0,sizeof(chw));
58     nt=0;
59     for(int i=1;i<=tot;i++) vis[i]=1;
60     for(int i=1;i<=tot;i++) if(!match[i])
61     {
62         nt++;
63         ffind(i,nt);
64     }
65     int q;
66     scanf("%d",&q);q<<=1;
67     op[0]=0;
68     for(int i=1;i<=q;i++)
69     {
70         vis[num[nx][ny]]=0;
71         if(match[num[nx][ny]])
72         {
73             int nw=match[num[nx][ny]];
74             match[nw]=match[num[nx][ny]]=0;
75             ret[i]=!ffind(nw,++nt);//找不到 必须点 必胜
76         }
77         else
78         {
79             ret[i]=0;//不在最优匹配中 不是必须点 必败
80         }
81         scanf("%d%d",&nx,&ny);
82     }
83     for(int i=1;i<=q;i+=2)
84      if(ret[i]&&ret[i+1]) op[++op[0]]=(i+1)/2;
85     printf("%d\n",op[0]);
86     for(int i=1;i<=op[0];i++) printf("%d\n",op[i]);
87 }
88
89 int main()
90 {
91     scanf("%d%d",&n,&m);
92     len=0;tot=0;
93     for(int i=1;i<=n;i++)
94     {
95         scanf("%s",s+1);
96         for(int j=1;j<=m;j++)
97         {
98             if(s[j]=='X') a[i][j]=0;
99             else if(s[j]=='O') a[i][j]=1;
100             else a[i][j+1]=0,nx=i,ny=j;
101             num[i][j]=++tot;
102         }
103     }
104     for(int i=1;i<=n;i++)
105      for(int j=1;j<=m;j++)
106      {
107          for(int k=1;k<=4;k++)
108          {
109              int xx=i+bx[k],yy=j+by[k];
110              if(xx<1||yy<1||xx>n||yy>m) continue;
111              if(a[xx][yy]==a[i][j]) continue;
112              ins(num[i][j],num[xx][yy]);
113          }
114      }
115     get_ans();
116     return 0;
117 }


View Code

2017-03-30 12:52:17
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: