zoj 3781 Paint the Grid Reloaded 最短路变形

来源:互联网 发布:矩阵变换 编辑:程序博客网 时间:2024/05/16 16:01

题意:给出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-8typedef 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;}/*23 6OOXOOXXOXOOXXXOXOO2*/


0 0