目录
注意:
1、专题系列难度随机。由于有些OJ网站不易被打开,无法查看原题目,所以所有的题目链接都指向VJ(Virtual Judge)中对应的题目。VJ中有题目的原出处,需要的自取!
2、为了让大家更易于理解AC码,每一道题的代码风格都用AI进行了优化。
A、Rumor(CodeForces 893C)
标签:并查集
AC码:
#include <bits/stdc++.h>
using namespace std;
#define endl "\n"
int pre[100005], a[100005];
int find(int x) {
return x == pre[x] ? x : pre[x] = find(pre[x]);
}
void join(int x, int y) {
int fx = find(x), fy = find(y);
if (a[fx] > a[fy]) {
pre[fx] = fy;
} else {
pre[fy] = fx;
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n, m;
cin >> n >> m;
for (int i = 1; i <= n; ++i) {
cin >> a[i];
pre[i] = i;
}
int x, y;
while (m--) {
cin >> x >> y;
join(x, y);
}
long long sum = 0;
for (int i = 1; i <= n; ++i) {
if (pre[i] == i) {
sum += a[i];
}
}
cout << sum;
return 0;
}
B、 Learning Languages(CodeForces 277A)
题目链接:Learning Languages(CodeForces 277A)
标签:并查集
AC码:
#include <bits/stdc++.h>
using namespace std;
#define endl "\n"
int pre[105], flag = 0;
int find(int x) {
return x == pre[x] ? x : pre[x] = find(pre[x]);
}
void join(int x, int y) {
int fx = find(x), fy = find(y);
if (fx != fy) {
pre[fx] = fy;
flag = 1;
}
}
int main() {
int n, m, ans = 0;
scanf("%d %d", &n, &m);
for (int i = 1; i <= n + m; ++i) {
pre[i] = i;
}
for (int i = 1; i <= n; ++i) {
int k;
scanf("%d", &k);
for (int j = k; j; --j) {
int x;
scanf("%d", &x);
join(x + n, i);
}
}
for (int i = 1; i <= n; ++i) {
if (pre[i] == i) {
ans++;
}
}
if (flag == 0) {
ans++;
}
printf("%d", ans - 1);
return 0;
}
C、 畅通工程(HDU 1232)
题目链接:畅通工程(HDU 1232)
标签:并查集
AC码:
#include <iostream>
using namespace std;
#define endl "\n"
int pre[1005];
int find(int x) {
return x == pre[x] ? x : pre[x] = find(pre[x]);
}
void join(int x, int y) {
int fx = find(x), fy = find(y);
if (fx != fy) {
pre[fx] = fy;
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n, m;
while (cin >> n && n != 0) {
cin >> m;
for (int i = 1; i <= n; ++i) {
pre[i] = i;
}
while (m--) {
int x, y;
cin >> x >> y;
join(x, y);
}
int cnt = 0;
for (int i = 1; i <= n; ++i) {
if (pre[i] == i) {
cnt++;
}
}
cout << cnt - 1 << endl;
}
return 0;
}
D、小希的迷宫(HDU 1272)
题目链接:小希的迷宫(HDU 1272)
标签:并查集
AC码:
#include <iostream>
using namespace std;
#define endl "\n"
int pre[100005], sign[100005];
int m, n, x, y, flag;
int find(int x) {
return x == pre[x] ? x : pre[x] = find(pre[x]);
}
void join(int x, int y) {
int fx = find(x), fy = find(y);
if (fx != fy) {
pre[fx] = fy;
} else {
flag = 0;
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
while (cin >> m >> n && (m != -1 && n != -1)) {
if (m == 0 && n == 0) {
cout << "Yes" << endl;
continue;
}
for (int i = 1; i < 100005; ++i) {
pre[i] = i;
sign[i] = 0;
}
sign[m] = sign[n] = 1;
flag = 1;
join(m, n);
while (cin >> x >> y && (x != 0 && y != 0)) {
join(x, y);
sign[x] = sign[y] = 1;
}
int k = 0;
for (int i = 1; i <= 100005; ++i) {
if (sign[i] && pre[i] == i) {
k++;
}
if (k > 1) {
flag = 0;
}
}
if (flag) {
cout << "Yes" << endl;
} else {
cout << "No" << endl;
}
}
return 0;
}
E、How Many Tables(HDU 1213)
题目链接:How Many Tables(HDU 1213)
标签:并查集
AC码:
#include <iostream>
using namespace std;
#define endl "\n"
int pre[1005];
int find(int x) {
return x == pre[x] ? x : pre[x] = find(pre[x]);
}
void join(int x, int y) {
int fx = find(x), fy = find(y);
if (fx != fy) {
pre[fx] = fy;
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t;
cin >> t;
while (t--) {
int n, m;
cin >> n >> m;
for (int i = 1; i <= n; ++i) {
pre[i] = i;
}
while (m--) {
int x, y;
cin >> x >> y;
join(x, y);
}
int cnt = 0;
for (int i = 1; i <= n; ++i) {
if (pre[i] == i) {
cnt++;
}
}
cout << cnt << endl;
}
return 0;
}
F、
题目链接:
标签:带权并查集
AC码:
在这里插入代码片
G、搭配购买(洛谷 P1455)
题目链接:搭配购买(洛谷 P1455)
标签:并查集+01背包
AC码:
#include <bits/stdc++.h>
using namespace std;
#define endl "\n"
const int MAXN = 100005;
int pre[MAXN];
int q[MAXN], v[MAXN];
int dp[MAXN];
int n, m, w;
int find(int x) {
return x == pre[x] ? x : pre[x] = find(pre[x]);
}
void join(int x, int y) {
int fx = find(x), fy = find(y);
if (fx != fy) {
q[fy] += q[fx];
v[fy] += v[fx];
pre[fx] = fy;
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin >> n >> m >> w;
for (int i = 1; i <= n; ++i) {
cin >> q[i] >> v[i];
pre[i] = i;
}
int x, y;
while (m--) {
cin >> x >> y;
join(x, y);
}
for (int i = 1; i <= n; ++i) {
if (pre[i] == i) {
for (int j = w; j >= q[i]; --j) {
dp[j] = max(dp[j], dp[j - q[i]] + v[i]);
}
}
}
cout << dp[w] << endl;
return 0;
}
H、
题目链接:
标签:带权并查集
AC码:
在这里插入代码片
I、修复公路(洛谷 P1111)
题目链接:修复公路(洛谷 P1111)
标签:并查集
AC码:
#include <bits/stdc++.h>
using namespace std;
#define endl "\n"
int pre[1005];
struct road {
int x, y, t;
};
bool cmp(road a1, road a2) {
return a1.t < a2.t;
}
int find(int x) {
return x == pre[x] ? x : pre[x] = find(pre[x]);
}
void join(int x, int y) {
int fx = find(x), fy = find(y);
if (fx != fy) {
pre[fx] = fy;
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n, m;
cin >> n >> m;
road a[m + 1];
for (int i = 1; i <= n; ++i) {
pre[i] = i;
}
for (int i = 1; i <= m; ++i) {
cin >> a[i].x >> a[i].y >> a[i].t;
}
sort(a + 1, a + m + 1, cmp);
for (int i = 1; i <= m; ++i) {
int cnt = 0;
join(a[i].x, a[i].y);
for (int j = 1; j <= n; ++j) {
if (j == pre[j]) {
cnt++;
}
}
if (cnt == 1) {
cout << a[i].t;
return 0;
}
}
cout << -1;
return 0;
}
J、家谱(洛谷 P2814)
题目链接:家谱(洛谷 P2814)
标签:并查集
AC码:
#include <bits/stdc++.h>
using namespace std;
#define endl "\n"
map<string, string> pre;
string find(string x) {
return x == pre[x] ? x : pre[x] = find(pre[x]);
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
string name, fa;
char ch;
cin >> ch;
while (ch != '$') {
cin >> name;
if (ch == '#') {
fa = name;
if (pre[name] == "") {
pre[name] = name;
}
} else if (ch == '+') {
pre[name] = fa;
} else {
cout << name << " " << find(name) << endl;
}
cin >> ch;
}
return 0;
}
结语
我只是一个A C M预习时长两年半的蒟蒻练习生,喜欢暴力,打表,面向样例编程,请各位键盘侠手下留情。