2017暑假训练之并查集
来源:互联网 发布:淘宝联盟 旧版 编辑:程序博客网 时间:2024/05/17 22:53
开学了,事情也越来越多了。我会努力补完的。
并查集基础应用
HDUOJ 1232 畅通工程
HDUOJ 1272 小希的迷宫
POJ 1182 食物链
向量偏移做法,并查集代码真的清晰美好哇!
HDUOJ 3038 How Many Answers Are Wrong
并查集基础应用
HDUOJ 1232 畅通工程
int f[maxn], _rank[maxn];void init(int n) {for (int i = 1; i <= n; ++i) f[i] = i, _rank[i] = 0;}//路径压缩的递归及非递归写法int find(int a) {//return f[a] == a ? a : f[a] = find(f[a]);int root = a;//寻找rootwhile (f[root] != root) root = f[root];int cur = a;//改变f[cur]while (cur != root) {int temp = f[cur];f[cur] = root;cur = temp;}return f[a];}//按秩归并void _union(int a, int b) {int fa = find(a), fb = find(b);if (fa == fb) return;if(_rank[fa] < _rank[fb]) f[fa] = fb;else {f[fb] = fa;if (_rank[fa] == _rank[fb]) _rank[fa]++;}}int main() {int n, m;while (scanf("%d", &n) && n) {init(n);scanf("%d", &m);while (m--) {int a, b;scanf("%d%d", &a, &b);_union(a, b);}int ans = 0;for (int i = 1; i <= n; ++i) if (f[i] == i) ans++;printf("%d\n", ans - 1);}return 0;}并查集的基础应用,蛮细节的一道题
HDUOJ 1272 小希的迷宫
int f[maxn]; vector<int> vis;void init() {vis.clear();for (int i = 1; i <= 100000; ++i) f[i] = i;}int find(int n) {//return f[n] == n ? n : f[n] = find(f[n]);int root = n;while (root != f[root]) root = f[root];int cur = n;while (cur != root) {int temp = f[cur];f[cur] = root;cur = temp;}return f[n];}bool _union(int a, int b) {int fa = find(a), fb = find(b);if (fa == fb) return false;f[fa] = fb;return true;}int main() {int a, b;while (scanf("%d%d", &a, &b)) {if (a == -1 && b == -1) break;if (a == 0 && b == 0) {printf("Yes\n");continue;}init();_union(a, b);vis.push_back(a);vis.push_back(b);bool ok = true;while (scanf("%d%d", &a, &b) && a) {//printf("fa = %d, fb = %d\n", f[a], f[b]);if (!_union(a, b)) ok = false;vis.push_back(a);vis.push_back(b);}//sort(vis.begin(), vis.end());vis.resize(unique(vis.begin(), vis.end()) - vis.begin());if (ok) {int cnt = 0;for (int i = 0; i < vis.size(); ++i)if (f[vis[i]] == vis[i]) cnt++;if (cnt > 1) ok = false;}if (ok) printf("Yes\n");else printf("No\n");}return 0;}经典带权并查集
POJ 1182 食物链
向量偏移做法,并查集代码真的清晰美好哇!
int f[maxn], rela[maxn];void init(int n) {for (int i = 1; i <= n; ++i) f[i] = i, rela[i] = 0;}int find(int a) {if (f[a] == a) return a;int t = f[a];f[a] = find(f[a]);rela[a] = (rela[a] + rela[t]) % 3;return f[a];}void _union(int a, int b, int re) {int fa = find(a), fb = find(b);f[fa] = fb;rela[fa] = ((re + rela[b] - rela[a]) % 3 + 3) % 3;}int main() {int n, k;scanf("%d%d", &n, &k);init(n);int op, a, b, cnt = 0;while (k--) {scanf("%d%d%d", &op, &a, &b);if (a > n || a < 1 || b > n || b < 1) ++cnt;else if (op == 1 && find(a) == find(b) && rela[a] != rela[b]) ++cnt;else if (op == 2 && find(a) == find(b) && ((rela[a] - rela[b])%3+3)%3 != 1) ++cnt;else _union(a, b, op - 1);}printf("%d\n", cnt);return 0;}种类并查集的做法,也十分清晰
int f[3 * maxn];int find(int x) {return x == f[x] ? x : f[x] = find(f[x]);}void unite(int a, int b) {int fa = find(a), fb = find(b);if (fa == fb) return;f[fa] = fb;}void init(int n) {for (int i = 1; i <= 3 * n; ++i) f[i] = i;}int main() {int n, q;scanf("%d%d", &n, &q);init(n);int op, a, b, ans = 0;while (q--) {scanf("%d%d%d", &op, &a, &b);if (a < 1 || a > n || b < 1 || b > n) ans++;else if (op == 1) {if (find(a) == find(b + n) || find(a) == find(b + 2 * n)) ans++;else unite(a, b), unite(a + n, b + n), unite(a + 2 * n, b + 2 * n);}else if (op == 2) {if (find(a) == find(b) || find(a) == find(b + 2 * n)) ans++;else unite(a, b + n), unite(a + n, b + 2 * n), unite(a + 2 * n, b);}}printf("%d\n", ans);return 0;}种类并查集的变式
HDUOJ 3038 How Many Answers Are Wrong
int f[maxn], res[maxn];void init(int n) {for (int i = 0; i <= n; ++i) f[i] = i, res[i] = 0;}int find(int x) {int t = f[x];if (t == x) return x;f[x] = find(t);res[x] = res[x] + res[t];return f[x];}void unite(int a, int b, int sum) {int la = find(a), lb = find(b);if (la < lb) f[lb] = la, res[lb] = res[a] + sum - res[b];else f[la] = lb, res[la] = res[b] - sum - res[a];}int main() {int n, q;while (~scanf("%d%d", &n, &q)) {init(n);int l, r, sum, ans = 0;while (q--) {scanf("%d%d%d", &l, &r, &sum); --l;if (find(l) == find(r) && res[r] - res[l] != sum) ans++;else unite(l, r, sum);}printf("%d\n", ans);}return 0;}
阅读全文
0 0
- 2017暑假训练之并查集
- 暑假训练(UVALive 5789-5799)(线段树+并查集+dp+桥)
- 2017暑假训练之二分法
- 2017暑假集训 div1 并查集(1)
- 2017暑假集训 div1 并查集(2)
- 寒假训练--并查集
- 省赛训练之并查集(五)
- 省赛训练之并查集(六)
- 2017暑假训练之树状数组
- 2017暑假训练之线段树
- 2017暑假训练之KMP、扩展KMP
- 2017/7/31训练日记(并查集基础)
- 寒假训练--并查集--电影节
- 寒假训练--并查集--Ubiquitous Religions
- 【训练题】极品飞车 (并查集)
- 并查集专题训练解题报告
- sduacm2016级暑假集训 搜索&并查集
- 2017暑假训练之字典树、AC自动机
- 【男人就爱你这样!学会六招勾心术…
- 【引发家事动力的8个祕诀,让孩子…
- 【与分数和平共处:父母对孩子合理…
- 【要喜欢自己不需要理由,只要觉得…
- 【让标籤黏不住的力量】「妈妈,同…
- 2017暑假训练之并查集
- 【思考霸凌与面对霸凌】小时候就读…
- 缓存: Null key returned for cache operation (maybe you are using named params on classes without debug
- [python] logging模块
- 【绝对性地原谅自己】我想在感情上…
- 【相处容易相爱难!】老师,我觉得…
- Spring Scheduled + Redis 实现分布式定时器(二)
- 【爱的长久,就是幸福吗?】在一起…
- 【还天真的孩子一个快乐童年】父母…