在遇到等差数列的构造题时(例如permutation), 要注意到总和为n * (n + 1) / 2, 并且这个值在n为奇数的时候可以被n整除,在n为偶数的时候不能被n整除。假设n是偶数的话,那么(n + 1)就是一个奇数,如果这个总和可以被n整除,那么结果应该是(n + 1) / 2, 而(n +1) / 2不是一个整数,所以矛盾
在图论的题目中,经常会遇到让我们找到一条合法的路径,那这个时候,我们可以注意他的限制条件,例如Resort - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)这个题中, 要求找到一个只有结尾是酒店的一条路径,如果正向去找的话,那么要搜的路径就很多了,但是如果反着来找,从酒店出发,避开其他的酒店,那么答案的复杂度就会少非常多。
还有一个例子是Maze - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)题目要求我们把k个位置从'.'变为'X', 如果说我们正常的思考哪个位置要变成'X'的话,那就很难思考,我们可以反过来,先走出一条长度为n - k的路,然后把其他k个位置全部堵上,这样就免去了思考变成x后是否合理的问题。
学了个找树的重心,枚举所有节点,dfs找每个子树的节点数,然后找到使得最大值最小的那个节点就行了,学这个的时候还解决了我的lambda表达式不能写递归的问题,主要是出在我定义vector数组的时候用的是vector<int> e[n + 1], 然后就会报错,改成vector<vector<int>> e(n + 1)就好了,我也不知道为什么,反正就是好了, 贴一下用lambda写的代码
#include <bits/stdc++.h>
#define int long long
#define INF 0x3f3f3f3f3f3f3f3f
#define ll long long
#define endl "\n"
#define PII pair<int,int>
#define fs first
#define sc second
#define pb push_back
#define rep(i, a, n) for (int i = a; i <= n; i++)
#define per(i, n, a) for (int i = n; i >= a; i--)
#define all(x) (x).begin(),(x).end()
#define sz(x) ((int)(x).size())
#define YES {cout<<"YES"<<endl;return;}
#define NO {cout<<"NO"<<endl;return;}
using ull = unsigned long long;
using namespace std;
// head
void solve() {
int n;
cin >> n;
vector<vector<int>> e(n + 1);
for (int i = 1; i < n; i++) {
int a, b;
cin >> a >> b;
e[a].pb(b);
e[b].pb(a);
}
int ans = INF;
vector<int> vis(100010);
auto dfs = [&](auto self, int x) -> int {
int res = 0, sum = 1;
vis[x] = 1;
for (auto i : e[x]) {
if (!vis[i]) {
int s = self(self, i);
sum += s;
res = max(res, s);
}
}
res = max(res, n - sum);
ans = min(res, ans);
return sum;
};
dfs(dfs, 1);
cout << ans << endl;
}
signed main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
int tt = 1;
// cin >> tt;
while (tt--) { solve(); }
return 0;
}
利用图论技巧解题:数列构造与路径搜索
本文讨论了解决编程竞赛中遇到的数列构造和图论问题策略,如等差数列和路径寻找中的优化方法,以及利用树的重心概念简化问题。还提及了lambda表达式的使用技巧和代码示例。
709

被折叠的 条评论
为什么被折叠?



