C++ std::function的簡單實現以及函式指標
阿新 • • 發佈:2021-10-27
基環樹上的沒有上司我舞會。我們需要把環斷開。可以任取環上一對點,將該邊斷開,就形成了一棵樹。然後從這邊的兩個端點(設為S,T)分別進行樹形DP。DP狀態設定和上司我舞會一樣,然後在f[0][T]和f[0][S]中取max,這樣可以保證兩點不會同時選到。
可以用並查集在建圖過程中建圖找環。
這個的實質就是在環上最後的一條邊要加入的時候不讓它加入
#include<bits/stdc++.h> #define rep(i,j,k) for(int i(j);i<=k;++i) #define drp(i,j,k) for(int i(j);i>=k;--i) #define repg(x) for(int i(G.head[x]);i;i=G.next[i]) #define bug cout<<"~~~~~~~~~~~~~"<<'\n'; using std::cin; using std::cout; typedef long long lxl; template<typename T> inline T max( T a, T b) { return a > b ? a : b; } template<typename T> inline T min( T a, T b) { return a < b ? a : b; } const int N = 1e5 + 79; struct graph { int head[N], tot, next[N << 1], ver[N << 1]; inline void add(int a, int b) { ver[++tot] = b; next[tot] = head[a]; head[a] = tot; } } G; int n, p[N], S, T, ans; namespace bingchaji { int fa[N]; int f[2][N]; inline int find(int x) { while(x != fa[x]) x = fa[x] = fa[fa[x]]; return x; } inline void DP(int x, int pre) { f[0][x] = 0; f[1][x] = p[x]; repg(x) { int y(G.ver[i]); if(y == pre)continue; DP(y, x); f[0][x] += max(f[1][y], f[0][y]); f[1][x] += f[0][y]; } } int main() { int x, y; rep(i, 1, n) { fa[i] = i; } rep(i, 1, n) { cin >> x >> y; ++x; ++y; if(find(x) == find(y)) { S = x; T = y; continue; } fa[find(x)] = find(y); G.add(x, y); G.add(y, x); } DP(S, 0); ans = max(ans, f[0][S]); DP(T, 0); ans = max(ans, f[0][T]); double k; cin >> k; cout << std::fixed << std::setprecision(1) << ans*k << '\n'; return 0; } } int main() { cin >> n; rep(i, 1, n) { cin >> p[i]; } bingchaji::main(); return 0; }
本文來自部落格園,作者:{2519},轉載請註明原文連結:https://www.cnblogs.com/QQ2519/p/15485372.html