乱七八糟的总结(2)

利用图论技巧解题:数列构造与路径搜索
本文讨论了解决编程竞赛中遇到的数列构造和图论问题策略,如等差数列和路径寻找中的优化方法,以及利用树的重心概念简化问题。还提及了lambda表达式的使用技巧和代码示例。

在遇到等差数列的构造题时(例如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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值