并查集
2016-10-19 15:55
120 查看
1、Codeforces 731C Socks
参考:http://www.voidcn.com/blog/morejarphone/article/p-6239786.html题意:给出 n 只袜子的颜色,每天选择两只袜子,每次能把一只袜子染色,问最少染色几只袜子能使的每天的袜子颜色一样
解题思路:
需要染成同一颜色的袜子用并查集维护,然后将并查集内所有袜子染成颜色出现最多的袜子的颜色
#include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> #include <queue> #include <vector> #include <stack> #include <map> #include <set> #include <cmath> #include <cctype> #include <bitset> #include <ctime> using namespace std; #define REP(i, n) for (int i = 0; i < (n); ++i) #define lson low, mid, _id<<1 #define rson mid+1, high, _id<<1|1 typedef long long ll; typedef unsigned long long ull; typedef unsigned int uint; typedef pair<int, int> Pair; const ull mod = 1e9 + 7; const int INF = 0x7fffffff; const int maxn = 2e5 + 10; int n, m, k, l, r; int c[maxn], pre[maxn], num[maxn]; vector<int> V[maxn]; int find_root(int x); int main() { #ifdef __AiR_H freopen("in.txt", "r", stdin); #endif // __AiR_H scanf("%d %d %d", &n, &m, &k); for (int i = 1; i <= n; ++i) { scanf("%d", &c[i]); } for (int i = 1; i <= n; ++i) { pre[i] = i; } while (m--) { scanf("%d %d", &l, &r); int fx = find_root(l), fy = find_root(r); if (fx != fy) { pre[fx] = fy; } } int ans = 0; for (int i = 1; i <= n; ++i) { V[find_root(i)].push_back(i); } memset(num, 0, sizeof(num)); for (int i = 1; i <= n; ++i) { if (V[i].size() == 0) { continue; } int size = V[i].size(), Max = 0; for (int j = 0; j < size; ++j) { ++num[c[V[i][j]]]; Max = max(Max, num[c[V[i][j]]]); } ans += size - Max; for (int j = 0; j < size; ++j) { num[c[V[i][j]]] = 0; } } printf("%d\n", ans); return 0; } int find_root(int x) { int r = x; while (pre[r] != r) { r = pre[r]; } while (pre[x] != r) { int t = pre[x]; pre[x] = r; x = t; } return r; }
2、Codeforces 722C Destroying Array
解题思路:倒着放要删除的数,维护一个最大值,每放一个数进行一次更新,每次更新将放入的这个数所在的区间的和与最大值比较,用并查集维护区间
#include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> #include <queue> #include <vector> #include <stack> #include <map> #include <set> #include <cmath> #include <cctype> #include <bitset> #include <ctime> using namespace std; #define lson low, mid, _id<<1 #define rson mid+1, high, _id<<1|1 typedef long long ll; typedef pair<ll, ll> Pair; const ll maxn = 1e5 + 10; ll n; ll pos[maxn], sum[maxn], pre[maxn]; bool vis[maxn]; vector<ll> ans; ll find_root(ll x); void join_unoin(ll x, ll y); int main() { #ifdef __AiR_H freopen("in.txt", "r", stdin); #endif // __AiR_H scanf("%I64d", &n); for (ll i = 1; i <= n; ++i) { scanf("%I64d", &sum[i]); pre[i] = i; } for (ll i = 1; i <= n; ++i) { scanf("%I64d", &pos[i]); } ll Max = 0; for (ll i = n; i > 1; --i) { vis[pos[i]] = true; if (vis[pos[i] - 1]) { join_unoin(find_root(pos[i]), find_root(pos[i] - 1)); } if (vis[pos[i] + 1]) { join_unoin(find_root(pos[i]), find_root(pos[i] + 1)); } Max = max(Max, sum[pos[i]]); ans.push_back(Max); } for (int i = ans.size() - 1; i >= 0; --i) { printf("%I64d\n", ans[i]); } printf("0\n"); return 0; } ll find_root(ll x) { ll r = x; while (r != pre[r]) { r = pre[r]; } while (pre[x] != r) { ll t = pre[x]; pre[x] = r; x = t; } return r; } void join_unoin(ll x, ll y) { sum[x] += sum[y]; pre[y] = x; }
3、Codeforces 217A Ice Skating
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <algorithm> #include <map> #include <queue> #include <stack> #include <set> #include <bitset> #include <ctime> #include <cctype> using namespace std; #define lson low, mid, _id<<1 #define rson mid + 1, high, _id<<1|1 typedef long long ll; typedef unsigned long long ull; typedef pair<int, int> Pair; const int mod = 1e9 + 7; const int INF = 0x7fffffff; const int maxn = 100 + 10; int n, cnt = 0; int x[maxn], y[maxn], pre[maxn]; bool vis[maxn]; int find_root(int a); int main() { #ifdef Floyd freopen("in.txt", "r", stdin); #endif scanf("%d", &n); for (int i = 0; i < n; ++i) { scanf("%d %d", &x[i], &y[i]); pre[i] = i; } for (int i = 0; i < n - 1; ++i) { for (int j = i + 1; j < n; ++j) { if (x[i] == x[j] || y[i] == y[j]) { int fx = find_root(i), fy = find_root(j); pre[fx] = fy; } } } memset(vis, false, sizeof(vis)); for (int i = 0; i < n; ++i) { int f = find_root(i); if (!vis[f]) { vis[f] = true; ++cnt; } } printf("%d\n", cnt - 1); return 0; } int find_root(int a) { int r = a; while (r != pre[r]) { r = pre[r]; } while (pre[a] != r) { int t = pre[a]; pre[a] = r; a = t; } return r; }
4、POJ 1182 食物链
参考:《挑战程序设计竞赛》P89#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#include <set>
#include <cmath>
#include <cctype>
#include <ctime>
#include <cassert>
using namespace std;
#define REP(i, n) for (int i = 0; i < (n); ++i)
#define eps 1e-9
typedef long long ll;
typedef pair<int, int> pii;
const int INF = 0x7fffffff;
const int maxn = 5e4 + 10;
int pre[maxn * 3];
int N, K, D, X, Y, ans = 0, fx_a, fx_b, fx_c, fy_a, fy_b, fy_c;
int find_root(int x);
int main() {
#ifdef __AiR_H
freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
#endif // __AiR_H
scanf("%d %d", &N, &K);
int t = N * 3;
for (int i = 1; i <= t; ++i) { pre[i] = i; }
while (K--) {
scanf("%d %d %d", &D, &X, &Y);
if (X > N || Y > N) { ++ans; continue; }
fx_a = find_root(X); fx_b = find_root(X + N); fx_c = find_root(X + 2 * N);
fy_a = find_root(Y); fy_b = find_root(Y + N); fy_c = find_root(Y + 2 * N);
if (D == 1) {
if (fx_a == fy_b || fx_a == fy_c) { ++ans; continue; }
pre[fx_a] = fy_a; pre[fx_b] = fy_b; pre[fx_c] = fy_c;
} else {
if (fx_a == fy_a || fx_a == fy_c) { ++ans; continue; }
pre[fx_a] = fy_b; pre[fx_b] = fy_c; pre[fx_c] = fy_a;
}
}
printf("%d\n", ans);
#ifdef __AiR_H
printf("Time used = %.2fs\n", (double)clock() / CLOCKS_PER_SEC);
#endif // __AiR_H
return 0;
}
int find_root(int x) {
int r = x;
while (pre[r] != r) { r = pre[r]; }
while (pre[x] != r) { int t = pre[x]; pre[x] = r; x = t; }
return r;
}
相关文章推荐
- 数据结构之并查集
- hdoj 1116 Play on Words 【并查集 + 欧拉】
- hdu 3234 Exclusive-OR[并查集] 施工中没写完233
- Educational Codeforces Round 36 (Rated for Div. 2) F. Imbalance Value of a Tree(并查集)
- xth的旅行——并查集的应用
- BZOJ 1104 POI2007 洪水pow 并查集
- 大连现场赛A题,匹配并查集
- HDU 2818 Building Blocks 带权并查集
- POJ-2236 wireless network 并查集
- hdu 1232 畅通工程(并查集)
- 3674: 可持久化并查集加强版
- Codeforces 25D-Roads not only in Berland 并查集
- kruskal 并查集优化
- p1403 种类并查集
- |洛谷|并查集|P3144 [USACO16OPEN]关闭农场Closing the Farm
- 食物链(带权并查集)
- Ural_1003 Parity(并查集)
- CF # 296 C Glass Carving (并查集 或者 multiset)
- 【模拟题】【集训系列1】【dp】【并查集】一套神奇的题
- 1118. Birds in Forest (25)——并查集