递归:明确函数目的,找到递归终止条件,关注本层内容。
树的递归
#include <iostream>
#include <cstring>
#include <algorithm>
#include <unordered_map>
#include <queue>
using namespace std;
const int N = 40;
int inorder[N], postorder[N];
unordered_map<int, int> l, r, pos;//l/r[i]表示i的左/右儿子,pos[i]表示i在中序遍历中的位置
int n;
//当前子树中序遍历是从il~ir,后序遍历是从pl~pr
int build(int il, int ir, int pl, int pr)
{
int root = postorder[pr];//根结点是后序遍历的最后一个点
int k = pos[root];//根结点在中序遍历中的位置是k
if (il < k) l[root] = build(il, k - 1, pl, k - 1 - il + pl);
if (ir > k) r[root] = build(k + 1, ir, k - il + pl, pr - 1);
return root;
}
void bfs(int root)//从根结点开始层序遍历
{
queue<int> Q;
Q.push(root);
while (Q.size())
{
int t = Q.front();
Q.pop();
cout << t << ' ';
if (l.count(t)) Q.push(l[t]);
if (r.count(t)) Q.push(r[t]);
}
}
int main()
{
cin >> n;
for (int i = 0; i < n; i++) cin >> postorder[i];
for (int i = 0; i < n; i++)
{
cin >> inorder[i];
pos[inorder[i]] = i;
}
int root = build(0, n - 1, 0, n - 1);
bfs(root);
return 0;
}
并查集
#include <iostream>
using namespace std;
const int N = 100010;
int p[N];
int find(int x)
{
if (p[x] != x) p[x] = find(p[x]);
return p[x];
}
int main()
{
int n, m;
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i ++ ) p[i] = i;
while (m -- )
{
char op[2];
int a, b;
scanf("%s%d%d", op, &a, &b);
if (*op == 'M') p[find(a)] = find(b);
else
{
if (find(a) == find(b)) puts("Yes");
else puts("No");
}
}
return 0;
}
连通块中点的数量
#include <iostream>
using namespace std;
const int N = 100010;
int n, m;
int p[N], cnt[N];
int find(int x)
{
if (p[x] != x) p[x] = find(p[x]);
return p[x];
}
int main()
{
cin >> n >> m;
for (int i = 1; i <= n; i ++ )
{
p[i] = i;
cnt[i] = 1;
}
while (m -- )
{
string op;
int a, b;
cin >> op;
if (op == "C")
{
cin >> a >> b;
a = find(a), b = find(b);
if (a != b)
{
p[a] = b;
cnt[b] += cnt[a];
}
}
else if (op == "Q1")
{
cin >> a >> b;
if (find(a) == find(b)) puts("Yes");
else puts("No");
}
else
{
cin >> a;
cout << cnt[find(a)] << endl;
}
}
return 0;
}
格子游戏
#include <iostream>
using namespace std;
const int N = 41000;
int p[N], n, m;
int get(int x, int y) {
return (x - 1) * n + y - 1;
}
inline int find(int x) {
if (x != p[x]) p[x] = find(p[x]);
return p[x];
}
int main () {
cin >> n >> m;
for (int i = 0; i <= n * n; i ++) p[i] = i;
int res = -1;
for (int i = 1; i <= m; i ++) {
int x, y;
char ch;
cin >> x >> y >> ch;
int a, b;
a = get(x, y), b = (ch == 'D') ? get(x + 1, y) : get(x, y + 1);
int pa = find(a), pb = find(b);
if (pa == pb) {
res = i;
break;
}
else {
p[pa] = pb;
}
}
if (~res) cout << res;
else puts("draw");
return 0;
}
搭配购买
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 10010;
int n, m, vol;
int v[N], w[N];
int p[N];
int f[N];
int find(int x)
{
if (p[x] != x) p[x] = find(p[x]);
return p[x];
}
int main()
{
cin >> n >> m >> vol;
for (int i = 1; i <= n; i ++ ) p[i] = i;
for (int i = 1; i <= n; i ++ ) cin >> v[i] >> w[i];
while (m -- )
{
int a, b;
cin >> a >> b;
int pa = find(a), pb = find(b);
if (pa != pb)
{
v[pb] += v[pa];
w[pb] += w[pa];
p[pa] = pb;
}
}
// 01背包
for (int i = 1; i <= n; i ++ )
if (p[i] == i)
for (int j = vol; j >= v[i]; j -- )
f[j] = max(f[j], f[j - v[i]] + w[i]);
cout << f[vol] << endl;
return 0;
}
程序自动分析
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <unordered_map>
using namespace std;
const int N = 200010;
int n, m;
int p[N];
unordered_map<int, int> S;
struct Query
{
int x, y, e;
}query[N];
int get(int x)
{
if (S.count(x) == 0) S[x] = ++ n;
return S[x];
}
int find(int x)
{
if (p[x] != x) p[x] = find(p[x]);
return p[x];
}
int main()
{
int T;
scanf("%d", &T);
while (T -- )
{
n = 0;
S.clear();
scanf("%d", &m);
for (int i = 0; i < m; i ++ )
{
int x, y, e;
scanf("%d%d%d", &x, &y, &e);
query[i] = {get(x), get(y), e};
}
for (int i = 1; i <= n; i ++ ) p[i] = i;
// 合并所有相等约束条件
for (int i = 0; i < m; i ++ )
if (query[i].e == 1)
{
int pa = find(query[i].x), pb = find(query[i].y);
p[pa] = pb;
}
// 检查所有不等条件
bool has_conflict = false;
for (int i = 0; i < m; i ++ )
if (query[i].e == 0)
{
int pa = find(query[i].x), pb = find(query[i].y);
if (pa == pb)
{
has_conflict = true;
break;
}
}
if (has_conflict) puts("NO");
else puts("YES");
}
return 0;
}