CF1073F Choosing Two Paths
Posted czxingchen
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF1073F Choosing Two Paths相关的知识,希望对你有一定的参考价值。
发现从顶点入手不太方便,我们从这个“公共部分最长”开始考虑问题,因为要求这一条公共部分的链最长,可以联想到树的直径,那么本题就是要求一条类似于直径的东西使两个端点除了直径这一条链之外还有不少于两个的儿子,我们只要把这两个儿子交叉输出一下就得到了本题的答案。
只要两次$dfs$就可以分别求出这一条链的两个端点了,$dfs$的时候维护一下最大和次大两个儿子更新答案即可。
时间复杂度$O(n)$。
Code:
#include <cstdio> #include <cstring> #include <iostream> using namespace std; typedef pair <int, int> pin; const int N = 2e5 + 5; int n, res, tot = 0, head[N], dep[N], fir[N], sec[N]; pin mx(0, 0); struct Edge { int to, nxt; } e[N << 1]; inline void add(int from, int to) { e[++tot].to = to; e[tot].nxt = head[from]; head[from] = tot; } inline void read(int &X) { X = 0; char ch = 0; int op = 1; for(; ch > ‘9‘ || ch < ‘0‘; ch = getchar()) if(ch == ‘-‘) op = -1; for(; ch >= ‘0‘ && ch <= ‘9‘; ch = getchar()) X = (X << 3) + (X << 1) + ch - 48; X *= op; } void dfs(int x, int fat, int depth) { dep[x] = depth; int son = 0; for(int i = head[x]; i; i = e[i].nxt) { int y = e[i].to; if(y == fat) continue; dfs(y, x, depth + 1); ++son; if(dep[fir[y]] > dep[fir[x]]) sec[x] = fir[x], fir[x] = fir[y]; else if(dep[fir[y]] > dep[sec[x]]) sec[x] = fir[y]; } if(!son) fir[x] = x; if(son >= 2) { pin tmp = pin(dep[x], dep[fir[x]] + dep[sec[x]]); if(tmp > mx) mx = tmp, res = x; } } int main() { read(n); for(int x, y, i = 1; i < n; i++) { read(x), read(y); add(x, y), add(y, x); } dfs(1, 0, 1); int ans1 = fir[res], ans2 = sec[res]; mx = pin(0, 0); memset(fir, 0, sizeof(fir)); memset(sec, 0, sizeof(sec)); dfs(res, 0, 1); int ans3 = fir[res], ans4 = sec[res]; printf("%d %d %d %d ", ans1, ans3, ans2, ans4); return 0; }
以上是关于CF1073F Choosing Two Paths的主要内容,如果未能解决你的问题,请参考以下文章
[CF1379C] Choosing flowers - 贪心,二分,排序