vector<int> w(n); DSU dsu(n); vector<pair<int, int>> nte; // none-tree edge vector<vector<int>> E(n); for (int i = 0; i < n; i++) { int u, v; cin >> u >> v >> w[i]; cin >> v; v--; if (!dsu.uno(u, v)) nte.push_back({ u, v }); else E[u].push_back(v), E[v].push_back(u); }
vector<array<ll, 2>> dp(n); auto dfs = [&](thisauto&& self, int u, int p) -> void { dp[u][0] = 0; dp[u][1] = w[u]; for (auto v : E[u]) { if (v == p) continue; self(v, u); dp[u][0] += max(dp[v][0], dp[v][1]); dp[u][1] += dp[v][0]; } }; auto solve = [&](int s) { dfs(s, -1); return dp[s][0]; };
ll sum = 0; for (auto [u, v] : nte) { sum += max(solve(u), solve(v)); } cout << sum << endl;
vector<vector<array<int, 3>>> E(n); for (int i = 0; i < n; i++) { int u, v, w; cin >> v >> w; u = i, v--; E[u].push_back({ w, v, i }); E[v].push_back({ w, u, i }); }
// 拓扑排序 queue<int> Q; vector<ll> dp(n), res(n); vector<int> vis(n), deg(n); for (int u = 0; u < n; ++u) { deg[u] = E[u].size(); if (deg[u] == 1) Q.push(u); } while (!Q.empty()) { int v = Q.front(); Q.pop(); vis[v] = 1; for (auto [w, u, id] : E[v]) { if (deg[u] > 1) { // v是u的子节点 res[u] = max({ res[u], res[v], dp[u] + dp[v] + w }); dp[u] = max(dp[u], dp[v] + w); // 这里写树形DP方程 if (--deg[u] == 1) Q.push(u); } } }
ll ress = 0; for (int u = 0; u < n; ++u) { if (vis[u]) continue; // 对于每一个基环树找环上的一个点 vector<ll> W; vector<int> V; V.push_back(u); W.push_back(0); vis[u] = 1; int fromid = -1; dofor(auto [w, v, id] : E[V.back()]){ if (deg[v] != 1 && id != fromid) { fromid = id; vis[v] = 1; V.push_back(v); W.push_back(w); res[u] = max(res[u], res[v]); break; } } while (u != V.back()); int cnt = V.size() - 1; V.resize(cnt << 1); W.resize(cnt << 1);
// 断环为链 for (int i = cnt + 1; i < (cnt << 1); i++) { W[i] = W[i - cnt]; V[i] = V[i - cnt]; } for (int i = 1; i < (cnt << 1); i++) { W[i] += W[i - 1]; }
deque<int> Q{ 0 }; for (int i = 1; i < (cnt << 1); i++) { if (!Q.empty() && i - Q.front() >= cnt) Q.pop_front(); // 毕业 res[u] = max(res[u], dp[V[i]] + dp[V[Q.front()]] + W[i] - W[Q.front()]); while (!Q.empty() && dp[V[i]] - W[i] >= dp[V[Q.back()]] - W[Q.back()]) Q.pop_back(); // 维护dp[V[i]]-W[i]最大值 Q.push_back(i); }