题意:给出n*m的只包含‘X’或‘O’的矩阵,可以将一个联通块内所有相连的X翻转成O,也可以将相连的O翻转成X,(相连指有一边相连)问翻转到同一种字符的最少次数
将联通块缩点,然后到别的联通块的距离就是翻转到该联通块需要的次数,对以每个联通块为起点跑一次最短路,求出最长距离,然后在最长距离里面找最短的就行了
/************************************************************************* > File Name: a.cpp > Author: zzx > Mail: 1640787991@qq.com > Created Time: 2015年03月11日 星期三 21时09分13秒 ************************************************************************/ #include <map> #include <set> #include <queue> #include <stack> #include <vector> #include <cmath> #include <cstdio> #include <cstdlib> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define lson l, mid, rt << 1 #define rson mid + 1, r, rt << 1 | 1 #define pi acos(-1.0) #define eps 1e-8 typedef long long ll; const int inf = 0x3f3f3f3f; const int N = 45; char a[N][N]; int mat[N][N]; bool vis[N][N]; int c[N*N]; int n, m; int cnt; int dir[4][2] = { 1, 0, -1, 0, 0, 1, 0, -1 }; int usd[N * N]; int dis[N*N]; struct edge{ int v, nxt, w; }e[N*N*N*N]; int head[N*N]; int k; queue <int> q; void init() { memset( vis, 0, sizeof ( vis ) ); memset( mat, 0, sizeof ( mat ) ); memset( c, 0, sizeof( c ) ); k = 0; memset( head, -1, sizeof( head ) ); } void add( int u, int v, int w ) { e[k].v = v; e[k].w = w; e[k].nxt = head[u]; head[u] = k++; e[k].v = u; e[k].w = w; e[k].nxt = head[v]; head[v] = k++; } void dfs( int x, int y, char col ) { for( int i = 0; i < 4; ++i ) { int xx = x + dir[i][0]; int yy = y + dir[i][1]; if( vis[xx][yy] && a[xx][yy] != col ) { add( mat[xx][yy], mat[x][y], 1 ); //printf("u: %d v: %d\n", mat[x][y], mat[xx][yy] ); continue; } if( !vis[xx][yy] && xx >= 1 && xx <= n && yy >= 1 && yy <= m && a[xx][yy] == col ) { vis[xx][yy] = 1; mat[xx][yy] = cnt; dfs( xx, yy, col ); } } } int spfa( int x, int y ) { int st = mat[x][y]; memset( usd, 0, sizeof( usd ) ); memset( dis, inf, sizeof( dis ) ); while( !q.empty( ) ) q.pop(); dis[ st ] = 0; usd[ st ] = 1; int res = -1; q.push(st); while( !q.empty( ) ) { int u = q.front(); q.pop(); usd[u] = 0; for( int i = head[u]; ~i; i = e[i].nxt ) { int v = e[i].v; //printf("u: %d v: %d\n", u, v); if( dis[v] > dis[u] + e[i].w ) { dis[v] = dis[u] + e[i].w; if( !usd[v] ) { usd[v] = 1; q.push( v ); } } } } for( int i = 1; i <= n*m; ++i ) if( dis[i] != inf && i != st ) res = max( res, dis[i] ); //printf("res: %d\n", res); return res; } int main() { int tot; scanf("%d", &tot); while( tot-- ) { init(); cnt = 0; scanf("%d%d", &n, &m); for( int i = 1; i <= n; i++ ) scanf("%s", a[i] + 1); for( int i = 1; i <= n; i++ ) { for( int j = 1; j <= m; ++j ) { if( !vis[i][j] ) { vis[i][j] = 1; mat[i][j] = ++cnt; char col = a[i][j]; dfs( i, j, col ); } } } if( cnt == 1 ) { puts("0"); continue; } else if( cnt == 2 ) { puts("1"); continue; } /* for( int i = 1; i <= n; ++i ) { for( int j = 1; j <= m; ++j ) printf("%d ", mat[i][j]); puts(""); } */ int ans = inf; for( int i = 1; i <= n; ++i ) { for( int j = 1; j <= m; ++j ) { if( !c[ mat[i][j] ] ) { c[ mat[i][j] ] = 1; ans = min( ans, spfa( i, j ) ); } } } printf("%d\n", ans); } return 0; } /* 2 3 6 OOXOOX XOXOOX XXOXOO 2 */