【bzoj1912】[Apio2010]patrol 巡逻
2017-04-12 16:15
267 查看
题目链接
1 2
3 1
3 4
5 3
7 5
8 5
5 6
30%的数据中,K = 1;
80%的数据中,每个村庄相邻的村庄数不超过 25;
90%的数据中,每个村庄相邻的村庄数不超过 150;
100%的数据中,3 ≤ n ≤ 100,000, 1 ≤ K ≤ 2。
有一条路的话显然把最长链的两端连起来比较划算。最长链为cnt的话可以减少cnt−1。
如果还有一条路呢,那么我们就是找另外一条最长链,这个第二条最长链可以与第一条有重复的边,但是如果重复一条边的话就会少减少2,这样可以吧第一次最长链的边全部赋值为-1然后直接求解就好了。最长链用树形DP求。
Description
Input
第一行包含两个整数 n, K(1 ≤ K ≤ 2)。接下来 n – 1行,每行两个整数 a, b, 表示村庄a与b之间有一条道路(1 ≤ a, b ≤ n)。Output
输出一个整数,表示新建了K 条道路后能达到的最小巡逻距离。Sample Input
8 11 2
3 1
3 4
5 3
7 5
8 5
5 6
Sample Output
11HINT
10%的数据中,n ≤ 1000, K = 1;30%的数据中,K = 1;
80%的数据中,每个村庄相邻的村庄数不超过 25;
90%的数据中,每个村庄相邻的村庄数不超过 150;
100%的数据中,3 ≤ n ≤ 100,000, 1 ≤ K ≤ 2。
题解
没有多余的路可以连的话答案就是(n−1)×2有一条路的话显然把最长链的两端连起来比较划算。最长链为cnt的话可以减少cnt−1。
如果还有一条路呢,那么我们就是找另外一条最长链,这个第二条最长链可以与第一条有重复的边,但是如果重复一条边的话就会少减少2,这样可以吧第一次最长链的边全部赋值为-1然后直接求解就好了。最长链用树形DP求。
#include<bits/stdc++.h> using namespace std; inline int read(){ int x = 0, f = 1; char c = getchar(); while(!isdigit(c)) { if(c == '-') f = -1; c = getchar(); } while(isdigit(c)) { x = x * 10 + c - '0'; c = getchar(); } return x * f; } const int N = 100000 + 10, M = 200000 + 10; int to[M], nxt[M], val[M], hd , c1 , c2 , tot = 1; int n, k, ans, mxp, cnt; inline void insert(int u, int v){ to[++tot] = v; nxt[tot] = hd[u]; hd[u] = tot; val[tot] = 1; to[++tot] = u; nxt[tot] = hd[v]; hd[v] = tot; val[tot] = 1; } void init(){ n = read(), k = read(); for(int i = 1; i < n; i++) insert(read(), read()); } int dfs(int u, int fa){ int mx1 = 0, mx2 = 0; for(int i = hd[u]; i; i = nxt[i]){ int v = to[i]; if(v != fa){ int tmp = val[i] + dfs(v, u); if(tmp > mx1) mx2 = mx1, mx1 = tmp, c2[u] = c1[u], c1[u] = i; else if(tmp > mx2) mx2 = tmp, c2[u] = i; } } if(mx1 + mx2 > cnt) cnt = mx1 + mx2, mxp = u; return mx1; } void work(){ ans = (n - 1) * 2; dfs(1, 0); ans -= cnt - 1; if(k == 2){ for(int i = c1[mxp]; i; i = c1[to[i]]) val[i] = val[i^1] = -1; for(int i = c2[mxp]; i; i = c1[to[i]]) val[i] = val[i^1] = -1; cnt = 0; dfs(1, 0); ans -= cnt - 1; } printf("%d\n", ans); } int main(){ init(); work(); return 0; }
相关文章推荐
- [BZOJ1912][Apio2010]patrol 巡逻(dfs+并查集+树形dp)
- [BZOJ1912][Apio2010]patrol 巡逻(树上最长链)
- bzoj 1912: [Apio2010]patrol 巡逻
- bzoj1912 [Apio2010]patrol 巡逻(树的直径[变式])
- [BZOJ 1912][APIO 2010]patrol 巡逻(树的直径)
- BZOJ 1912 [Apio2010]patrol 巡逻 - 树形DP(树的直径)
- [BZOJ 1912][Apio2010]patrol 巡逻:树的直径
- BZOJ 1912 [Apio2010]patrol 巡逻
- BZOJ1912[Apio2010]patrol 巡逻
- BZOJ1912 [Apio2010]patrol 巡逻
- 【BZOJ1912】[Apio2010]patrol 巡逻 树形DP
- 【bzoj1912】[Apio2010]patrol 巡逻(树上最长链)
- bzoj 1912: [Apio2010]patrol 巡逻【不是dp是枚举+堆】
- 【bzoj1912】 Apio2010—patrol 巡逻
- BZOJ1912[Apio2010]patrol 巡逻
- 【bzoj1912】[Apio2010]patrol 巡逻
- 【BZOJ】【1912】【APIO2010】patrol巡逻
- bzoj 1912 [Apio2010]patrol 巡逻 树形dp
- bzoj1912 [Apio2010]patrol 巡逻
- 【bzoj1912】[Apio2010] patrol 巡逻 树形dp