首页 > 代码库 > ZOJ - 3781 Paint the Grid Reloaded 题解
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 题解
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。