hdu1198并查集
来源:互联网 发布:淘宝差评在哪里解释 编辑:程序博客网 时间:2024/05/20 23:30
之前忘了并查集使用的方式,导致我把图中的11张图看成了各自的一类,然后就悲剧了=-=
简述这道题的意思,就是有11种suqare然后将这些可以组成各种大小的田地。现在它给你一块由这些suqare组成的田地
,因为每块地都有pipe,要保证这些田都被灌溉你要判断这块地需要多少个wellspring。
首先说下并查集的思路:题目要求是输入m行,n列,而且m和n是不超过50,算出来是2500,说明使用并查集是可以解决的
时间复杂度是O(m*n),并查集最需要注意的地方就是要注意初始化。这道题wa了4次,前两次是没找出自己的并查集是写错的
,后两次改成正确的并查集,然而却忘了初始化_(:зゝ∠)_。
#include<iostream>#include<fstream>#include<cstring>using namespace std;struct Squares{ bool up; bool down; bool left; bool right; int root;};int p[2510];Squares S[12];int disjoint[12] = { 0 };bool isjudge[2510] = { 0 };int m, n;int map[60][60];void init(){ S[1].up = true; S[1].down = false; S[1].left = true; S[1].right = false; S[1].root = 1; S[2].up = true; S[2].down = false; S[2].left = false; S[2].right = true; S[2].root = 2; S[3].up = false; S[3].down = true; S[3].left = true; S[3].right = false; S[3].root = 3; S[4].up = false; S[4].down = true; S[4].left = false; S[4].right = true; S[4].root = 4; S[5].up = true; S[5].down = true; S[5].left = false; S[5].right = false; S[5].root = 5; S[6].up = false; S[6].down = false; S[6].left = true; S[6].right = true; S[6].root = 6; S[7].up = true; S[7].down = false; S[7].left = true; S[7].right = true; S[7].root = 7; S[8].up = true; S[8].down = true; S[8].left = true; S[8].right = false; S[8].root = 8; S[9].up = false; S[9].down = true; S[9].left = true; S[9].right = true; S[9].root = 9; S[10].up = true; S[10].down = true; S[10].left = false; S[10].right = true; S[10].root = 10; S[11].up = true; S[11].down = true; S[11].left = true; S[11].right = true; S[11].root = 11;}void initroot(){ for (int i = 0; i <= m*n; i++) { p[i] = i; }}int findroot(int a){ int root = a; while (p[root] != root) root = p[root]; int i = a, j; while (i != root) { j = p[i]; p[i] = root; i = j; } return root;}void merge(int a, int b){ int fx = findroot(a), fy = findroot(b); if (fx != fy) { p[fx] = fy; }}int ans;void solve(){ ans = 0; int loc; int locup; int locdown; int locleft; int locright; for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { loc = map[i][j]; if (i - 1 >= 0)//up is right { locup = map[i - 1][j]; if (S[locup].down&&S[loc].up) { merge(i*n + j, (i - 1)*n + j); } } if (i + 1 < m)//down is right { locdown = map[i + 1][j]; if (S[locdown].up&&S[loc].down) { merge(i *n + j, (i + 1)*n + j); } } if (j + 1 < n)//right is right { locright = map[i][j + 1]; if (S[locright].left&&S[loc].right) { merge(i *n + j, i*n + j + 1); } } if (j - 1 >= 0) { locleft = map[i][j - 1]; if (S[locleft].right&&S[loc].left) { merge(i*n + j, i*n + j - 1); } } } } for (int i = 0; i < m*n; i++) findroot(i); for (int i = 0; i < m*n; i++) { if (isjudge[p[i]] == false) { ans++; isjudge[p[i]] = true; } } printf("%d\n", ans);}int main(){ init(); while (scanf_s("%d%d", &m, &n)) { //getchar(); initroot(); memset(isjudge, false, sizeof(isjudge)); memset(map, 0, sizeof(map)); if (m + n == -2) break; char c; for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { cin >> c; //scanf_s("%c", &c); map[i][j] = c - 'A' + 1; } //getchar(); } solve(); }}
0 0
- hdu1198 并查集
- hdu1198并查集
- hdu1198--并查集
- hdu1198(并查集)
- hdu1198并查集
- hdu1198 并查集
- hdu1198 并查集
- 并查集应用hdu1198
- hdu1198 二维并查集
- hdu1198—并查集
- hdu1198(DFS/并查集)
- HDU1198(Farm Irrigation)-并查集
- HDU1198-Farm Irrigation(并查集应用)
- hdu1198 并查集(值得复习)
- Hdu1198 - Farm Irrigation - 并查集
- hdu1198(并查集的应用)
- hdu1198 Farm Irrigation ----并查集
- HDU1198(不必暴力,并查集应用,0MS)
- HDU 1003 Max Sum【贪心】
- uva10375 Choose and Divide(唯一分解定理)
- 内存设置好可以为电脑提速
- Activity生命周期
- vim visual操作备忘
- hdu1198并查集
- 专访罗升阳:老罗的Android之旅
- A Simple Problem with Integers
- 大数模板(读入字符串,c++重载)
- Objective-C_字典、集合、数组排序
- [笔记][Java7并发编程实战手册]2.5使用Lock实现同步一
- 零基础学python-目录
- 控制线程顺序执行
- 异常图结构