您的位置:首页 > 其它

并查集

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: