您的位置:首页 > 大数据 > 人工智能

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;

}

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