码迷,mamicode.com
首页 > 其他好文 > 详细

ZOJ 3781 Paint the Grid Reloaded (最短路)

时间:2014-07-29 21:40:22      阅读:358      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   使用   os   io   for   

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3781

题意:

在n*m矩阵的图定义连通区域为x值或y值相同且颜色相同的连通,连通具有传递性

每次可以把一个连通区域颜色反转(O变X,X变O)

问把所有块的颜色变为X最小的步数

 

方法:

很巧妙的最短路问题,先建图,然后以每个顶点为起点,找单源最短路的最大的值(也就是最深的深度),然后这个值取min

建图:相邻的块连边权1的边(即:通过1次反转可以使得两个连通块变为一个连通块)

 

注意:

floyd会TLE,需要邻接表建图

因为是稀疏图且边权为1,所以使用bfs或者spfa或者dijkstra均可

 

代码:spfa

bubuko.com,布布扣
  1 // #pragma comment(linker, "/STACK:102400000,102400000")
  2 #include <cstdio>
  3 #include <iostream>
  4 #include <cstring>
  5 #include <string>
  6 #include <cmath>
  7 #include <set>
  8 #include <list>
  9 #include <map>
 10 #include <iterator>
 11 #include <cstdlib>
 12 #include <vector>
 13 #include <queue>
 14 #include <stack>
 15 #include <algorithm>
 16 #include <functional>
 17 using namespace std;
 18 typedef long long LL;
 19 #define ROUND(x) round(x)
 20 #define FLOOR(x) floor(x)
 21 #define CEIL(x) ceil(x)
 22 const int maxn = 1610;
 23 const int maxm = 100010;
 24 const int inf = 0x3f3f3f3f;
 25 const LL inf64 = 0x3f3f3f3f3f3f3f3fLL;
 26 const double INF = 1e30;
 27 const double eps = 1e-6;
 28 const int P[4] = {0, 0, -1, 1};
 29 const int Q[4] = {1, -1, 0, 0};
 30 const int PP[8] = { -1, -1, -1, 0, 0, 1, 1, 1};
 31 const int QQ[8] = { -1, 0, 1, -1, 1, -1, 0, 1};
 32 char mtx[50][50];
 33 int label[50][50];
 34 int g[maxn][maxn];
 35 struct Edge
 36 {
 37     int u, v;
 38     int w;
 39     int next;
 40     Edge(int _u = -1, int _v = -1, int _w = -1, int _next = -1): u(_u), v(_v), w(_w), next(_next) {}
 41 } edge[maxm];
 42 int n;
 43 int N, M;
 44 int head[maxn];
 45 int d[maxn];
 46 int en;
 47 int ans;
 48 void addse(int u, int v, int w)
 49 {
 50     edge[en] = Edge(u, v, w, head[u]);
 51     head[u] = en++;
 52 }
 53 void adde(int u, int v, int w)
 54 {
 55     addse(u, v, w);
 56     addse(v, u, w);
 57 }
 58 void init()
 59 {
 60     memset(g, 0x3f, sizeof(g));
 61     memset(head, -1, sizeof(head));
 62     en = 0;
 63     memset(label, -1, sizeof(label));
 64     ans = 0;
 65 }
 66 void input()
 67 {
 68     scanf("%d%d", &N, &M);
 69     for (int i = 0; i < N; i++)
 70         scanf("%s", mtx[i]);
 71 }
 72 void debug()
 73 {
 74     //
 75 }
 76 void dfs(int x, int y, char ch)
 77 {
 78     label[x][y] = n;
 79     for (int i = 0; i < 4; i++)
 80     {
 81         int nx = x + P[i];
 82         int ny = y + Q[i];
 83         if (nx < 0 || nx >= N || ny < 0 || ny >= M) continue;
 84         if (label[nx][ny] == -1 && mtx[nx][ny] == ch)
 85         {
 86             dfs(nx, ny, ch);
 87         }
 88     }
 89 }
 90 void build()
 91 {
 92     n = 0;
 93     for (int i = 0; i < N; i++)
 94     {
 95         for (int j = 0; j < M; j++)
 96         {
 97             if (label[i][j] == -1)
 98             {
 99                 dfs(i, j, mtx[i][j]);
100                 n++;
101             }
102         }
103     }
104 
105     for (int i = 0; i < N; i++)
106     {
107         for (int j = 0; j < M; j++)
108         {
109             for (int p = 0; p < 4; p++)
110             {
111                 int nx = i + P[p];
112                 int ny = j + Q[p];
113                 if (nx < 0 || nx >= N || ny < 0 || ny >= M) continue;
114                 g[label[i][j]][label[nx][ny]] = g[label[nx][ny]][label[i][j]] = 1;
115             }
116         }
117     }
118 
119     for (int i = 0; i < n; i++)
120     {
121         for (int j = i + 1; j < n; j++)
122         {
123             if (g[i][j]==1)
124             {
125                 adde(i, j, 1);
126                 // cout << j << " ";
127             }
128         }
129         // cout << endl;
130     }
131 }
132 int spfa(int s)
133 {
134     int cnt[maxn];
135     int mark[maxn];
136     queue<int> Q;
137     for (int i = 0; i < n; ++i) d[i] = inf;
138     memset(mark, 0, sizeof(mark));
139     memset(cnt, 0, sizeof(cnt));
140     d[s] = 0;
141     Q.push(s);
142     mark[s] = 1;
143     cnt[s]++;
144     while (Q.size())
145     {
146         int u = Q.front();
147         Q.pop();
148         mark[u] = 0;
149         for (int i = head[u]; i != -1; i = edge[i].next)
150         {
151             int v = edge[i].v;
152             int w = edge[i].w;
153             if (d[u] + w < d[v])
154             {
155                 d[v] = d[u] + w;
156                 if (mark[v] == 0)
157                 {
158                     mark[v] = 1;
159                     Q.push(v);
160                     if (++cnt[v] > n) return inf; //有负环,可以用DFS找
161                 }
162             }
163         }
164     }
165     int ret = -1;
166     for (int i = 0; i < n; i++)
167     {
168         ret = max(ret, d[i]);
169     }
170     if (ret == -1) return inf;
171     // cout<<"ret:"<<ret<<endl;
172     return ret;
173 }
174 void solve()
175 {
176     build();
177 
178     ans = inf;
179     for (int i = 0; i < n; i++)
180     {
181         ans = min(ans, spfa(i));
182     }
183     printf("%d\n", ans);
184 }
185 void output()
186 {
187     //
188 }
189 int main()
190 {
191     // std::ios_base::sync_with_stdio(false);
192 #ifndef ONLINE_JUDGE
193     freopen("in.cpp", "r", stdin);
194 #endif
195 
196     int T;
197     scanf("%d", &T);
198     while (T--)
199     {
200         init();
201         input();
202         solve();
203         output();
204     }
205     return 0;
206 }
View Code

 

ZOJ 3781 Paint the Grid Reloaded (最短路),布布扣,bubuko.com

ZOJ 3781 Paint the Grid Reloaded (最短路)

标签:style   blog   http   color   使用   os   io   for   

原文地址:http://www.cnblogs.com/xysmlx/p/3876318.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!