ZOJ3781

题目链接:http://acm.hust.edu.cn/vjudge/contest/view.action?cid=107574#problem/B

题目大意:一幅图只含'o','x'问将它们反转为同一种符号所需最小步数(翻一个点时,周围相同的点都会翻转)

题目思路:dfs处理缩点,然后建图,bfs求最短路

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <stack>
#include <cctype>
#include <queue>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <climits>
#define lson root<<1,l,mid
#define rson root<<1|1,mid+1,r
#define fi first
#define se second
#define ping(x,y) ((x-y)*(x-y))
#define mst(x,y) memset(x,y,sizeof(x))
#define Min(x,y) (x<y?x:y)
#define Max(x,y) (x>y?x:y)
using namespace std;
#define gamma 0.5772156649015328606065120 //欧拉常数
#define MOD 100000007
#define inf 0x3f3f3f3f
#define N 100050
#define maxn 10001000
typedef long long LL;
typedef pair<int,int> PII;


struct Node{
    int to,next;
}node[5000]; int n_cnt;
int n,m,dir[][2]= {{1,0},{-1,0},{0,1},{0,-1}};
char pic[50][50];
int num[50][50],dye,head[5000];
set<int>s[5000];

inline int judge(int x,int y)
{
    return x>0&&x<=n&&y>0&&y<=m;
}

inline void add(int x,int y)
{
    node[n_cnt].to=y;
    node[n_cnt].next=head[x];
    head[x]=n_cnt++;
}

void dfs(int x,int y,char ch)
{
    for(int i=0; i<4; ++i)
    {
        int xx=x+dir[i][0];
        int yy=y+dir[i][1];
        if(judge(xx,yy))
        {
            if(!num[xx][yy]&&pic[xx][yy]==ch) {num[xx][yy]=num[x][y];dfs(xx,yy,ch);}
            else if(num[xx][yy]&&!s[num[x][y]].count(num[xx][yy]))
            {
                s[num[x][y]].insert(num[xx][yy]);
                s[num[xx][yy]].insert(num[x][y]);
                add(num[x][y],num[xx][yy]);
                add(num[xx][yy],num[x][y]);
            }
        }
    }
}

int bfs(int _x)
{
    queue<int>q; q.push(_x);
    int d[5000],res=-1; mst(d,-1);
    d[_x]=0;
    while(!q.empty())
    {
        int u=q.front(); q.pop();
        res=Max(res,d[u]);
        for(int i=head[u]; i+1; i=node[i].next)
        {
            int e=node[i].to;
            if(d[e]==-1)
            {
                d[e]=d[u]+1;
                q.push(e);
            }
        }
    }
    return res;
}

int main()
{
    int i,j,x,y,v,group;
    scanf("%d",&group);
    while(group--)
    {
        for(i=1; i<5000; ++i) s[i].clear();
        n_cnt=0;
        scanf("%d%d",&n,&m);
        for(i=1; i<=n; ++i)
            scanf("%s",pic[i]+1);
        mst(num,0);
        mst(head,-1);
        dye=1;
        for(i=1; i<=n; ++i)
            for(j=1; j<=m; ++j)
                if(!num[i][j])
                {
                    num[i][j]=dye;
                    dfs(i,j,pic[i][j]);
                    ++dye;
                }
        int ans=inf;
        for(i=1; i<dye; ++i)
            ans=Min(ans,bfs(i));
        printf("%d\n",ans);
    }
    return 0;
}

 

posted @ 2016-04-10 12:53  Kurokey  阅读(282)  评论(0编辑  收藏  举报