diff --git a/P2607.cpp b/P2607.cpp new file mode 100644 index 0000000..06e8c79 --- /dev/null +++ b/P2607.cpp @@ -0,0 +1,49 @@ +#include +#define int long long +using namespace std; +int n; +int p[1000005]; +vector fri[1000005]; +int bc[1000005]; +vector> ST; +int find(int now) { + if(bc[now] == now) return now; + return bc[now] = find(bc[now]); +} +int dps[1000005][2], dpt[1000005][2]; +void dfs(int now, bool s, int from, int st) { + if(s) dps[now][1] = p[now]; + else dpt[now][1] = p[now]; + if(s && now == st) dps[now][1] = LLONG_MIN; + else if(!s && now == st) dpt[now][1] = LLONG_MIN; + for(int i:fri[now]) { + if(i == from) continue; + dfs(i, s, now, st); + if(s) dps[now][1] += dps[i][0], dps[now][0] += max(dps[i][0], dps[i][1]); + else dpt[now][1] += dpt[i][0], dpt[now][0] += max(dpt[i][0], dpt[i][1]); + } +} +signed main() { + scanf("%lld", &n); + for(int i = 1; i <= n; ++i) { + bc[i] = i; + } + for(int i = 1, v; i <= n; ++i) { + scanf("%lld%lld", &p[i], &v); + if(find(i) == find(v)) { + ST.push_back({i, v}); + } else { + fri[i].push_back(v); + fri[v].push_back(i); + bc[find(i)] = find(v); + } + } + int ans = 0; + for(auto [s, t]:ST){ + dfs(s, 1, -1, s); + dfs(t, 0, -1, t); + ans += max(max(dps[s][0], dps[s][1]), max(dpt[t][1], dpt[t][0])); + } + printf("%lld\n", ans); + return 0; +} \ No newline at end of file diff --git a/P2607.md b/P2607.md new file mode 100644 index 0000000..5075e2b --- /dev/null +++ b/P2607.md @@ -0,0 +1,53 @@ +# P2607 [ZJOI2008] 骑士 + +## 题目描述 + +Z 国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英。他们劫富济贫,惩恶扬善,受到社会各界的赞扬。 + +最近发生了一件可怕的事情,邪恶的 Y 国发动了一场针对 Z 国的侵略战争。战火绵延五百里,在和平环境中安逸了数百年的 Z 国又怎能抵挡的住 Y 国的军队。于是人们把所有的希望都寄托在了骑士团的身上,就像期待有一个真龙天子的降生,带领正义打败邪恶。 + +骑士团是肯定具有打败邪恶势力的能力的,但是骑士们互相之间往往有一些矛盾。每个骑士都有且仅有一个自己最厌恶的骑士(当然不是他自己),他是绝对不会与自己最厌恶的人一同出征的。 + +战火绵延,人民生灵涂炭,组织起一个骑士军团加入战斗刻不容缓!国王交给了你一个艰巨的任务,从所有的骑士中选出一个骑士军团,使得军团内没有矛盾的两人(不存在一个骑士与他最痛恨的人一同被选入骑士军团的情况),并且,使得这支骑士军团最具有战斗力。 + +为了描述战斗力,我们将骑士按照 $1$ 至 $n$ 编号,给每名骑士一个战斗力的估计,一个军团的战斗力为所有骑士的战斗力总和。 + +## 输入格式 + +第一行包含一个整数 $n$,描述骑士团的人数。 + +接下来 $n$ 行,每行两个整数,按顺序描述每一名骑士的战斗力和他最痛恨的骑士。 + +## 输出格式 + +应输出一行,包含一个整数,表示你所选出的骑士军团的战斗力。 + +## 输入输出样例 #1 + +### 输入 #1 + +``` +3 +10 2 +20 3 +30 1 + +``` + +### 输出 #1 + +``` +30 +``` + +## 说明/提示 + +#### 数据规模与约定 + +对于 $30\%$ 的测试数据,满足 $n \le 10$; + +对于 $60\%$ 的测试数据,满足 $n \le 100$; + +对于 $80\%$ 的测试数据,满足 $n \le 10 ^4$。 + +对于 $100\%$ 的测试数据,满足 $1\le n \le 10^6$,每名骑士的战斗力都是不大于 $10^6$ 的正整数。 \ No newline at end of file