题目链接
大家的 Blog 里面都是做过的题目,只有我的里面什么都没有
那我也开始写一点吧
刷着刷着 DP 不知怎的就出来一道这个题……用时 2 hours 后怒而删两个文件重构……
然后过了……过了……
至今不知道前两遍错在哪里……
Code - first time:连通块染色 +建图,然后二分,广搜判断
Code - second time:连通块染色 +建图,并查集维护连通块大小,做伪 Kruskal
Code - third time:二分,广搜判断
1 #include <queue> 2 #include <cstdio> 3 #include <cctype> 4 #include <cstring> 5 #include <iostream> 6 #include <algorithm> 7 using namespace std; 8 9 const int maxn = 500 + 10; 10 const int maxk = 500 * 500 + 10; 11 int n, h[maxn][maxn], vis[maxn][maxn], flag; 12 int f[4][2] = { 0, 1, 1, 0, -1, 0, 0, -1 }; 13 14 inline int Abs(int x) { return x > 0 ? x : -x; } 15 16 inline bool Breath_fs(int sx, int sy, int c) { 17 queue<pair<int, int> > q; 18 q.push(make_pair(sx, sy)), vis[sx][sy] = 1; 19 int cnt = 1; 20 while( !q.empty() ) { 21 int x = q.front().first, y = q.front().second; 22 for(int i = 0; i < 4; ++i) { 23 int tx = x + f[i][0], ty = y + f[i][1]; 24 if( tx < 1 || tx > n || ty < 1 || ty > n ) continue; 25 if( Abs(h[x][y] - h[tx][ty]) > c || vis[tx][ty] ) continue; 26 ++cnt, vis[tx][ty] = 1, q.push(make_pair(tx, ty)); 27 } 28 q.pop(); 29 } 30 return cnt + 1 > ((n * n) >> 1) + ((n * n) & 1); 31 } 32 33 inline bool Check(int x) { 34 memset(vis, 0, sizeof vis), flag = 0; 35 for(int i = 1; i <= n; ++i) { 36 for(int j = 1; (!flag && j <= n); ++j) 37 if( !vis[i][j] ) flag = flag | Breath_fs(i, j, x); 38 if( flag ) break; 39 } 40 return flag; 41 } 42 43 int main(int argc, char const *argv[]) 44 { 45 freopen("nanjolno.in", "r", stdin); 46 freopen("nanjolno.out", "w", stdout); 47 48 scanf("%d", &n); 49 for(int i = 1; i <= n; ++i) for(int j = 1; j <= n; ++j) scanf("%d", &h[i][j]); 50 int lef = 0, righ = 1000000, mid = (lef + righ) >> 1, ans = 0; 51 for( ; lef <= righ; mid = (lef + righ) >> 1) 52 Check(mid) ? ans = mid, righ = mid - 1 : lef = mid + 1; 53 printf("%d ", ans); 54 55 fclose(stdin), fclose(stdout); 56 return 0; 57 }
—— 晨意微寒秋渐深,侧畔无事俏佳人。