星尘斗士 (stars)
时间限制: 1 Sec 内存限制: 128 MB
题目描述
请开 long long
。
若众人皆丧气,则我谒见谏言。———— R a i n y 7 Rainy7 Rainy7
在浩瀚无垠的宇宙中,分布着许许多多的文明,它们之间经常起冲突。
一次,一个文明派出大批星舰进攻地球,地球人被打得落荒而逃。
此时在地球上,巨神 R a i n y 7 Rainy7 Rainy7 天天吊打集训队,已经感到厌烦了,于是, R a i n y 7 Rainy7 Rainy7 便去吊打外星人了。
R a i n y 7 Rainy7 Rainy7 使用魔法,将这 n n n 艘星舰封锁住了。然而,这些星舰都有护盾保护, R a i n y 7 Rainy7 Rainy7 要想方设法破除它们。
星舰的封锁关系可以看成一棵树。一开始, R a i n y 7 Rainy7 Rainy7 可以任选一艘星舰,然后直接解除它的护盾。紧接着, R a i n y 7 Rainy7 Rainy7 可以进行 n n n 次操作,每次选择一艘未被护盾保护的星舰,然后直接摧毁它,并且获得它被摧毁前所在的全都是未被摧毁的星舰的连通块的大小的魔法值。一艘星舰被摧毁后,与它直接相连且未被摧毁的星舰的护盾会全部被解除。
R
a
i
n
y
7
Rainy7
Rainy7 想知道,自己最多能获得多少魔法值。她只用了
11451
4
−
1919810
114514^{-1919810}
114514−1919810s就解决了问题,于是把问题抛给了您。
如图所示,加粗的星舰表示已经被摧毁。若选择 2 2 2 号星舰,将会获得 4 4 4 点魔法值,并且解除 3 , 5 , 6 3,5,6 3,5,6 的护盾。若选择 9 9 9 号星舰,将会获得 3 3 3 点魔法值,并且解除 7 , 8 7,8 7,8 的护盾。
输入
第一行一个数
n
n
n,表示星舰数量。
接下来
n
−
1
n-1
n−1 行,每行两个数
u
,
v
u,v
u,v,表示星舰的相连关系。
输出
一行一个数,表示最多能获得的魔法值。
样例输入
【样例1】
9
1 2
2 3
2 5
2 6
1 4
4 9
9 7
9 8
【样例2】
5
1 2
1 3
2 4
2 5
样例输出
【样例1】
36
【样例2】
14
数据范围
2 ≤ n ≤ 2 × 1 0 5 2 \leq n \leq 2 \times10^5 2≤n≤2×105
思路
#pragma GCC optimize(3,"Ofast","inline")
#include <iostream>
#include <cstdio>
#include <cstring>
#include <set>
#include <map>
#include <algorithm>
#include <unordered_map>
#include <vector>
using namespace std;
#define ls (rt<<1)
#define rs (rt<<1|1)
typedef long long ll;
template <typename T>
inline void read(T &x) {
x = 0;
static int p;
p = 1;
static char c;
c = getchar();
while (!isdigit(c)) {
if (c == '-')p = -1;
c = getchar();
}
while (isdigit(c)) {
x = (x << 1) + (x << 3) + (c - 48);
c = getchar();
}
x *= p;
}
template <typename T>
inline void print(T x) {
static int cnt;
static int a[50];
cnt = 0;
do {
a[++cnt] = x % 10;
x /= 10;
} while (x);
for (int i = cnt; i >= 1; i--)putchar(a[i] + '0');
puts("");
}
const int mod = 1e9+7;
const int inf = 0x3f3f3f3f;
const int maxn = 2e5+10;
int n;
ll ans;
int siz[maxn];
vector<int>e[maxn];
int f[maxn];
ll dp1[maxn];
ll dp2[maxn];
void dfs1(int u,int fa) {
siz[u] = 1;
for (int v:e[u]) {
if (v == fa) continue;
f[v]=u;
dfs1(v, u);
siz[u] += siz[v];
dp1[u] += dp1[v];
}
dp1[u] += siz[u];
}
void dfs2(int u,int fa) {
if (u != fa) {
dp2[u] = dp1[fa] - siz[fa] + dp2[fa] - dp1[u] + n - siz[u];
}
for (int v:e[u]) {
if (v == fa) continue;
dfs2(v, u);
}
}
inline void work() {
read(n);
for (int i = 1, u, v; i < n; i++) {
read(u);
read(v);
e[u].emplace_back(v);
e[v].emplace_back(u);
}
dfs1(1, 0);
dfs2(1, 1);
for (int i = 1; i <= n; i++) {
ans = max(ans, dp1[i] + dp2[i] - siz[i]);
}
print(ans + n);
}
int main() {
int T = 1;
//scanf("%d", &T);
while (T--) {
work();
}
return 0;
}