1 solutions
-
0
90分代码,最后一个点TLE。我已经找到原因了,希望有同学也能找到。
然后希望大家能总结出代码T的常见原因,增加比赛实战经验。
#include <bits/stdc++.h> using namespace std; typedef long long LL; const int N = 1e6 + 10; LL f[N][2], ans; vector<int> g[N]; int p[N]; // 战斗力 // fa[i]:骑士i痛恨的人 // 虽然很想把自己痛恨的人当作儿子,但做到后面就会发现 // 还是存成基环外向树,在DP的时候比较好处理 int fa[N]; int n; bool vis[N]; // 要找环,所以得加vis int x; // 环上断开的边的一个端点 void dfs(int u) { // 在“没有上司的舞会”代码基础上,要多记录几个状态 vis[u] = 1; f[u][0] = 0; f[u][1] = p[u]; for (int v : g[u]) { // 只有环边端点x会被重复访问一次 if (v == x) continue; dfs(v); f[u][0] += max(f[v][0], f[v][1]); f[u][1] += f[v][0]; } } // 解决点u所在基环树的问题 void solve(int u) { // 找环,锁定环上的一条边 (x,y) x = u; while (fa[x] && !vis[fa[x]]) { x = fa[x]; vis[x] = 1; // cout << x << "\n"; } dfs(x); // 保证x不被选中,那么x的fa就可以被选中 // 在DP里写起来更方便(与保证x一定被选相比)) LL t = f[x][0]; // 然后从断边的另一个端点进入DFS x = fa[x]; dfs(x); ans += max(t, f[x][0]); } int main() { ios::sync_with_stdio(0), cin.tie(0); cin >> n; int v; for (int i = 1; i <= n; i++) { cin >> p[i] >> v; g[v].push_back(i); fa[i] = v; } for (int i = 1; i <= n; i++) if (!vis[i]) solve(i); cout << ans; return 0; }
- 1
Information
- ID
- 164
- Time
- 1000ms
- Memory
- 512MiB
- Difficulty
- 9
- Tags
- # Submissions
- 56
- Accepted
- 6
- Uploaded By