并查集
普通并查集
格子游戏
参考题解
#include <iostream>
#include <cstdio>
using namespace std;
const int N = 4e4+5;
int n, m;
int p[N];
int find(int x)
{
if(x != p[x]) p[x] = find(p[x]);
return p[x];
}
int get(int x, int y)
{
return x*n+y;
}
int main()
{
cin >> n >> m;
for(int i = 0; i < N; ++ i) p[i] = i;
int ans = 0;
for(int step = 1; step <= m; ++ step)
{
int x, y;
scanf("%d%d", &x, &y);
x -= 1, y -= 1;
char op[2];
scanf("%s", op);
if(ans > 0) continue;
int a, b;
a = get(x, y);
if(op[0] == 'D')
{
b = get(x+1, y);
}
else
{
b = get(x, y+1);
}
a = find(a), b = find(b);
if(a == b)
{
ans = step;
}
p[a] = b;
}
if(ans > 0)
{
printf("%d\n", ans);
}
else
{
cout << "draw" << endl;
}
return 0;
}
搭配购买
参考题解
并查集+01背包
#include <iostream>
#include <cstdio>
using namespace std;
const int N = 1e4+5;
int n, m, w;
int p[N];
int cost[N], value[N];
int find(int x)
{
if(x != p[x]) p[x] = find(p[x]);
return p[x];
}
int dp[N];
int main()
{
cin >> n >> m >> w;
for(int i = 1; i <= n; ++ i) p[i] = i;
for(int i = 1; i <= n; ++ i)
{
scanf("%d%d", cost+i, value+i);
}
for(int i = 1; i <= m; ++ i)
{
int a, b;
scanf("%d%d", &a, &b);
int pa = find(a), pb = find(b);
if(pa == pb) continue;
p[pa] = pb;
cost[pb] += cost[pa];
value[pb] += value[pa];
}
for(int i = 1; i <= n; ++ i)
{
if(p[i] == i)
{
for(int j = w; j >= cost[i]; -- j)
{
dp[j] = max(dp[j], dp[j-cost[i]] + value[i]);
}
}
}
cout << dp[w] << endl;
return 0;
}
程序自动分析
参考题解
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <unordered_map>
using namespace std;
const int N = 1e5+5, M = 2*N;
int n;
int p[M];
int find(int x)
{
if(x != p[x]) p[x] = find(p[x]);
return p[x];
}
unordered_map<int, int> ha;
int m = 0;
//离散化
int get(int x)
{
if(!ha.count(x)) ha[x] = m++;
return ha[x];
}
struct Query
{
int a, b;
int type;
bool operator<(const Query& t) const
{
return type >= t.type;
}
}query[N];
int main()
{
int t;
cin >> t;
while(t --)
{
ha.clear();
cin >> n;
m = 0;
for(int i = 0; i < n; ++ i)
{
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
query[i] = {get(a), get(b), c};
}
for(int i = 0; i < m; ++ i) p[i] = i;
for(int i = 0; i < n; ++ i)
{
if(query[i].type == 1)
{
int pa = find(query[i].a), pb = find(query[i].b);
p[pa] = pb;
}
}
bool ans = true;
for(int i = 0; i < n; ++ i)
{
if(query[i].type == 0)
{
int pa = find(query[i].a), pb = find(query[i].b);
if(pa == pb)
{
ans = false;
break;
}
}
}
if(ans) puts("YES");
else puts("NO");
}
return 0;
}
带权并查集
银河英雄传说
参考题解
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <deque>
#include <string>
#include <unordered_map>
using namespace std;
const int INF = 0x3f3f3f3f, N = 3e4+5;
typedef long long LL;
int n;
int p[N], s[N], d[N];
int find(int x)
{
if(x != p[x])
{
int root = find(p[x]);
d[x] += d[p[x]];
p[x] = root;
}
return p[x];
}
int main()
{
for(int i = 1; i < N; ++ i)
{
p[i] = i;
s[i] = 1;
}
int T;
cin >> T;
while(T --)
{
char op[2];
int a, b;
scanf("%s%d%d", op, &a, &b);
int pa = find(a), pb = find(b);
if(op[0] == 'M')
{
if(pa != pb)
{
d[pa] = s[pb];
s[pb] += s[pa];
p[pa] = pb;
}
}
else
{
if(pa == pb)
{
cout << max(abs(d[a]-d[b])-1, 0) << endl;
}
else
{
cout << "-1" << endl;
}
}
}
return 0;
}








浙公网安备 33010602011771号