ZOJ3781 Paint the Grid Reloaded
2017-07-10 13:49
281 查看
题目:给一个n*m的X O构成的格子,对一个点操作可以使与它相连通的所有一样颜色的格子翻转颜色(X—>O或O—>X),问给定的矩阵最少操作多少次可以全部变成一样的颜色。
(1 <= N, M <= 40)
Input:
3 3
XOX
OXO
XOX
Output:
2
分析:1.把相通且颜色相同的的联通块缩成一个点
2.把相连的联通块之间连边
3.以每个点为根,bfs求树的深度,最小的深度即为最少的翻转次数
技能:1.有环的图求“直径”不能用dfs
2.矩阵初始化边界注意 0~n+1
代码:
#include<bits/stdc++.h>
using namespace std;
#define rep(i,j,k) for (int i=j;i<=k;++i)
#define dep(i,j,k) for (int i=j;i>=k;--i)
#define to e[i].v
#define Cl(a) memset(a,0,sizeof(a))
#define N 60
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};
struct node{
int v,next;
}e[N*N*2];
bool vis
,link[N*N][N*N],v[N*N];
int a
,dist[N*N],head[N*N],q[N*N];
int id,scc,n,m,pos,t;
char s
;
int read()
{
int f=1,x=0;char ch=getchar();
for (;ch>'9'||ch<'0';ch=getchar()) if (ch=='-') f=-1;
for (;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0';
return x*f;
}
void dfs(int x,int y,int scc,int pd)
{
vis[x][y]=1; a[x][y]=scc;
rep(i,0,3)
{
int nx=x+dx[i],ny=y+dy[i];
if (a[nx][ny]==pd && !vis[nx][ny]) dfs(nx,ny,scc,pd);
}
}
void bfs(int u)
{
int l=0,r=1;
for (v[q[1]=u]=1,dist[u]=0;l^r;)
for (int i=head[u=q[++l]];i;i=e[i].next)
if (!v[to]) v[q[++r]=to]=1,dist[to]=dist[u]+1;
}
void add(int u,int v)
{
e[id].v=v; e[id].next=head[u]; head[u]=id++;
}
int main()
{
t=read();
for (;t--;)
{
n=read(); m=read();
rep(i,0,n+1) rep(j,0,m+1) a[i][j]=-1,vis[i][j]=0;
Cl(head); Cl(link);
rep(i,1,n)
{
scanf("%s",s+1);
rep(j,1,m)
if (s[j]=='X') a[i][j]=1;
else a[i][j]=0;
}
scc=0;
rep(i,1,n) rep(j,1,m)
if (!vis[i][j])
{
++scc;
dfs(i,j,scc,a[i][j]);
}
// rep(i,1,n) {rep(j,1,m) printf("%d ",a[i][j]);puts("");}
id=1;
rep(i,1,n) rep(j,1,m)
{
int x=i+1,y=j;
if ((x<=n) && (a[i][j]^a[x][y]) && (!link [a[i][j]] [a[x][y]]))
{
add(a[i][j],a[x][y]); add(a[x][y],a[i][j]);
link [a[i][j]] [a[x][y]] = link [a[x][y]] [a[i][j]] = 1;
}
x=i,y=j+1;
if ((y<=m) && (a[i][j]^a[x][y]) && (!link [a[i][j]] [a[x][y]]))
{
add(a[i][j],a[x][y]); add(a[x][y],a[i][j]);
link [a[i][j]] [a[x][y]] = link [a[x][y]] [a[i][j]] = 1;
}
}
// Cl(v); bfs(1); dist[0]=-1; pos=0; rep(i,1,scc) if (dist[i]>dist[pos]) pos=i;
// Cl(v); bfs(pos); dist[0]=-1; pos=0; rep(i,1,scc) if (dist[i]>dist[pos]) pos=i;
int as=1234567890;
rep(i,1,scc)
{
Cl(v); bfs(i); dist[0]=-1; pos=0;
rep(j,1,scc) if (dist[j]>dist[pos]) pos=j;
as=min(as,dist[pos]);
}
printf("%d\n",as);
}
return 0;
}
(1 <= N, M <= 40)
Input:
3 3
XOX
OXO
XOX
Output:
2
分析:1.把相通且颜色相同的的联通块缩成一个点
2.把相连的联通块之间连边
3.以每个点为根,bfs求树的深度,最小的深度即为最少的翻转次数
技能:1.有环的图求“直径”不能用dfs
2.矩阵初始化边界注意 0~n+1
代码:
#include<bits/stdc++.h>
using namespace std;
#define rep(i,j,k) for (int i=j;i<=k;++i)
#define dep(i,j,k) for (int i=j;i>=k;--i)
#define to e[i].v
#define Cl(a) memset(a,0,sizeof(a))
#define N 60
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};
struct node{
int v,next;
}e[N*N*2];
bool vis
,link[N*N][N*N],v[N*N];
int a
,dist[N*N],head[N*N],q[N*N];
int id,scc,n,m,pos,t;
char s
;
int read()
{
int f=1,x=0;char ch=getchar();
for (;ch>'9'||ch<'0';ch=getchar()) if (ch=='-') f=-1;
for (;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0';
return x*f;
}
void dfs(int x,int y,int scc,int pd)
{
vis[x][y]=1; a[x][y]=scc;
rep(i,0,3)
{
int nx=x+dx[i],ny=y+dy[i];
if (a[nx][ny]==pd && !vis[nx][ny]) dfs(nx,ny,scc,pd);
}
}
void bfs(int u)
{
int l=0,r=1;
for (v[q[1]=u]=1,dist[u]=0;l^r;)
for (int i=head[u=q[++l]];i;i=e[i].next)
if (!v[to]) v[q[++r]=to]=1,dist[to]=dist[u]+1;
}
void add(int u,int v)
{
e[id].v=v; e[id].next=head[u]; head[u]=id++;
}
int main()
{
t=read();
for (;t--;)
{
n=read(); m=read();
rep(i,0,n+1) rep(j,0,m+1) a[i][j]=-1,vis[i][j]=0;
Cl(head); Cl(link);
rep(i,1,n)
{
scanf("%s",s+1);
rep(j,1,m)
if (s[j]=='X') a[i][j]=1;
else a[i][j]=0;
}
scc=0;
rep(i,1,n) rep(j,1,m)
if (!vis[i][j])
{
++scc;
dfs(i,j,scc,a[i][j]);
}
// rep(i,1,n) {rep(j,1,m) printf("%d ",a[i][j]);puts("");}
id=1;
rep(i,1,n) rep(j,1,m)
{
int x=i+1,y=j;
if ((x<=n) && (a[i][j]^a[x][y]) && (!link [a[i][j]] [a[x][y]]))
{
add(a[i][j],a[x][y]); add(a[x][y],a[i][j]);
link [a[i][j]] [a[x][y]] = link [a[x][y]] [a[i][j]] = 1;
}
x=i,y=j+1;
if ((y<=m) && (a[i][j]^a[x][y]) && (!link [a[i][j]] [a[x][y]]))
{
add(a[i][j],a[x][y]); add(a[x][y],a[i][j]);
link [a[i][j]] [a[x][y]] = link [a[x][y]] [a[i][j]] = 1;
}
}
// Cl(v); bfs(1); dist[0]=-1; pos=0; rep(i,1,scc) if (dist[i]>dist[pos]) pos=i;
// Cl(v); bfs(pos); dist[0]=-1; pos=0; rep(i,1,scc) if (dist[i]>dist[pos]) pos=i;
int as=1234567890;
rep(i,1,scc)
{
Cl(v); bfs(i); dist[0]=-1; pos=0;
rep(j,1,scc) if (dist[j]>dist[pos]) pos=j;
as=min(as,dist[pos]);
}
printf("%d\n",as);
}
return 0;
}
相关文章推荐
- zoj3781 Paint the Grid Reloaded --- 缩点 bfs
- ZOJ3781 - Paint the Grid Reloaded(最短路)
- ZOJ3781 - Paint the Grid Reloaded(缩点+最短路)
- [ZOJ3781]Paint the Grid Reloaded
- ZOJ3781-Paint the Grid Reloaded(缩点+bfs)
- zoj 3781 Paint the Grid Reloaded
- ZOJ 3781 Paint the Grid Reloaded
- Paint the Grid Reloaded ZOJ - 3781
- ZOJ 3781 Paint the Grid Reloaded 缩点+bfs
- ZOJ 3781 Paint the Grid Reloaded 题解 (dfs缩点+BFS)
- ZOJ 3781 - Paint the Grid Reloaded(缩点dfs+bfs)
- zoj 3781 Paint the Grid Reloaded (bfs)
- ZOJ 3781 Paint the Grid Reloaded ( BFS(重点是对问题的分析) )
- 3781 -- Paint the Grid Reloaded
- ZOJ Paint the Grid Reloaded
- ZOJ-3781-Paint the Grid Reloaded【11th浙江省赛】【连通块缩点】【spfa】【好题】
- zoj 3781 Paint the Grid Reloaded
- ZOJ 3781 Paint the Grid Reloaded (最短路)
- ZOJ-3781-Paint the Grid Reloaded 缩点+建图+spfa
- 2014 Super Training #4 E Paint the Grid Reloaded --联通块缩点+BFS