ZOJ 3781 Paint the Grid Reloaded 连通块
LINK:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3781
题意:n*m只由OX组成的矩阵,可以选择某一连通块变成另一个字符,问整个矩阵变成相同的最小次数
思路:对所有连通块编号,根据是否与其他联通块相连建边,最后得到图后枚举以某起点(代表某连通块)所能到的最大距离求它们的最小值即可。
关键还是在于模型的转换,这方面我好像有点欠缺orz
/** @Date : 2017-03-30-15.09 * @Author : Lweleth (SoungEarlf@gmail.com) * @Link : https://github.com/ * @Version : */ #include<bits/stdc++.h> #define LL long long #define PII pair #define MP(x, y) make_pair((x),(y)) #define fi first #define se second #define PB(x) push_back((x)) #define MMG(x) memset((x), -1,sizeof(x)) #define MMF(x) memset((x),0,sizeof(x)) #define MMI(x) memset((x), INF, sizeof(x)) using namespace std; const int INF = 0x3f3f3f3f; const int N = 1e5+20; const double eps = 1e-8; int dir[4][2] = {0,1,0,-1,1,0,-1,0}; char mp[50][50]; bool vis[50][50]; int vt[50][50];//num bool mr[2000][2000]; int dic[2000]; vectoredg[2000]; int cnt; int n, m; void dfs(int x, int y, char k) { if(vis[x][y]) { if(mp[x][y] != k && vt[x][y] != -1 && !mr[vt[x][y]][cnt]) { mr[vt[x][y]][cnt] = 1; mr[cnt][vt[x][y]] = 1; edg[cnt].PB(vt[x][y]); edg[vt[x][y]].PB(cnt); } return ; } if(mp[x][y] == k) { vis[x][y] = 1; vt[x][y] = cnt; for(int i = 0; i < 4; i++) { int a = x + dir[i][0]; int b = y + dir[i][1]; if(a > 0 && b > 0 && a <= n && b <= m) dfs(a, b, k); } } } void spfa(int x) { bool e[2000] = {0}; MMI(dic); queue q; e[x] = 1; dic[x] = 0; q.push(x); while(!q.empty()) { int nw = q.front(); q.pop(); e[nw] = 0; for(int i = 0; i < edg[nw].size(); i++) { int np = edg[nw][i]; int ds = 1 + dic[nw]; if(dic[np] > ds) { dic[np] = ds; if(!e[np]) e[np] = 1, q.push(np); } } } } int main() { int T; cin >> T; while(T--) { MMF(vis); MMF(vt); scanf("%d%d", &n, &m); for(int i = n*m + 1; i >= 0; i--) edg[i].clear(), MMF(mr[i]); getchar(); for(int i = 1; i <= n; i++) { for(int j = 1; j <= m; j++) { scanf("%c", &mp[i][j]); } getchar(); } /*for(int i = 1; i <= n; i++) { for(int j = 1; j <= m; j++) printf("%c", mp[i][j]); printf("\n"); }*/ cnt = 0; for(int i = 1; i <= n; i++) { for(int j = 1; j <= m; j++) { if(!vis[i][j]) { dfs(i, j, mp[i][j]); cnt++; } } } int ans = INF; for(int i = 0; i < cnt; i++) { spfa(i); int ma = 0; for(int j = 0; j < cnt; j++) ma = max(ma, dic[j]); ans = min(ans, ma); } printf("%d\n", ans); } return 0; } /* 1 4 4 OXOX XOXO OXOX XOXO */