ZOJ - 3781 Paint the Grid Reloaded 题解

Posted SHYI

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ZOJ - 3781 Paint the Grid Reloaded 题解相关的知识,希望对你有一定的参考价值。

题目大意:

  给一个n*m的X O构成的格子,对一个点操作可以使与它相连通的所有一样颜色的格子翻转颜色(X—>O或O—>X),问给定的矩阵最少操作多少次可以全部变成一样的颜色。

思路:

  1.每次操作都将本身所在的连通块与和自己相邻的不同颜色的连通块变成同一种颜色,也就是变成一个连通块了,那么要使n次操作后全部变成一样的颜色,也就是从某点出发到达其余所有点。
  2.因此dfs把连通块缩成点,然后相邻的连通块之间建边,枚举以每个点为根的情况,bfs求出每种情况的深度,取最小的即为答案。

反思:

  1.hea数组初始赋-1会死循,要赋0。
  2.M要开60,50的话要WA。

代码:

 1 #include<cstdio>
 2 const int dx[4]={-1,0,0,1},dy[4]={0,-1,1,0},M=60,N=3600;
 3 int cnt,num,b[M][M],d[N],q[N],v[N<<1],hea[N],nex[N<<1];
 4 bool f,a[M][M],c[N][N],vis[N];
 5 char s[M];
 6 
 7 void sd(int x,int y)
 8 {
 9     b[x][y]=cnt;
10     for (int i=0,u,v;i<4;++i)
11         if (b[u=x+dx[i]][v=y+dy[i]]==0 && a[u][v]==a[x][y]) sd(u,v);
12 }
13 
14 void add(int x,int y) { v[++num]=y,nex[num]=hea[x],hea[x]=num; }
15 
16 int dep(int x)
17 {
18     int l=0,r=1,y,i; 
19     for (vis[q[1]=x]=f,d[x]=0;l^r;)
20         for (i=hea[x=q[++l]];i;i=nex[i])
21             if (vis[y=v[i]]^f) vis[q[++r]=y]=f,d[y]=d[x]+1;
22     return d[q[r]];
23 }
24 
25 int main()
26 {
27     int T,n,m,i,j,k,x,y,u,v;
28     for (scanf("%d",&T);T;--T)
29     {
30         scanf("%d%d",&n,&m);
31         for (i=1;i<=n;++i)
32             for (scanf("%s",s),j=1;j<=m;++j)
33                 if (s[j-1]==O) a[i][j]=1; else a[i][j]=0;
34         for (i=cnt=num=0;i<n+2;++i) b[i][0]=b[i][m+1]=-1;
35         for (i=0;i<m+2;++i) b[0][i]=b[n+1][i]=-1;
36         for (i=1;i<=n;++i)
37             for (j=1;j<=m;++j) b[i][j]=0;
38         for (i=1;i<=n;++i)
39             for (j=1;j<=m;++j)
40                 if (!b[i][j]) ++cnt,sd(i,j);
41         for (i=1;i<=cnt;++i)
42             for (j=1;j<=cnt;++j) c[i][j]=1;
43         for (i=1;i<=cnt;++i) hea[i]=0;
44         for (i=1;i<=n;++i)
45             for (j=1;j<=m;++j)
46                 for (u=b[i][j],k=2;k<4;++k)
47                     if (~(v=b[x=i+dx[k]][y=j+dy[k]]) && c[u][v] && u^v)
48                         add(u,v),add(v,u),c[u][v]=c[v][u]=0;
49         for (i=1;i<=cnt;++i) vis[i]=f;
50         for (y=cnt,i=1;i<=cnt;++i)
51             if (f=!f,(x=dep(i))<y) y=x;
52         printf("%d\n",y);
53     }
54     return 0;
55 }

 

以上是关于ZOJ - 3781 Paint the Grid Reloaded 题解的主要内容,如果未能解决你的问题,请参考以下文章

ZOJ - 3781 Paint the Grid Reloaded 题解

ZOJ - 3780-Paint the Grid Again-(拓扑排序)

ZOJ 3780 Paint the Grid Again(隐式图拓扑排序)

ZOJ 3780 E - Paint the Grid Again 拓扑排序

Paint the Grid Reloaded(缩点,DFS+BFS)

1411. Number of Ways to Paint N × 3 Grid