感受有點降智c++
首先設環長爲\(len\),很容易推導出
\[ R(1) = \frac{\sum_{i = 1}^{N} C_{i} k^{dep[i]}}{1 - k^{len}} \]
我好像以爲彷佛\(len\)越大底下越小了,太降智了,len越大底下越大spa
因此環長越小越好,因此咱們若是動了一條環邊,就是把它儘可能往1連code
枚舉環上,強制要求環上上的點不選,除開1到1的後繼的那條邊,咱們就得到了一棵樹get
咱們但願\(dp\)出改了m個點最大是多少,顯然改就必定直接連到1it
設\(f[u][j][d]\)爲\(u\)這個點,子樹裏改了\(j\)個點,咱們硬點\(u\)到\(1\)的距離是\(d\)class
轉移的話分\(u\)有沒有被連到1im
若是被連到1了,那麼就從\(max(f[v][k][1],f[v][k][2])\)轉移過來,要加上\(C_{u} \times K\)db
不然就從\(max(f[v][k][d + 1],f[v][k][1])\)轉移過來,要加上\(C_{u} \times K^{d}\)di
第二維是個揹包,直接作就好了make
#include <bits/stdc++.h> #define fi first #define se second #define pii pair<int,int> #define mp make_pair #define pb push_back #define space putchar(' ') #define enter putchar('\n') #define eps 1e-10 #define ba 47 #define MAXN 5005 //#define ivorysi using namespace std; typedef long long int64; typedef unsigned int u32; typedef double db; template<class T> void read(T &res) { res = 0;T f = 1;char c = getchar(); while(c < '0' || c > '9') { if(c == '-') f = -1; c = getchar(); } while(c >= '0' && c <= '9') { res = res * 10 +c - '0'; c = getchar(); } res *= f; } template<class T> void out(T x) { if(x < 0) {x = -x;putchar('-');} if(x >= 10) { out(x / 10); } putchar('0' + x % 10); } int N,M; int fa[65]; db K[65],C[65],f[65][65][65],g[65]; bool nouse[65]; void dfs(int u,int dep) { for(int v = 2 ; v <= N ; ++v) { if(fa[v] == u) dfs(v,dep + 1); } for(int d = dep ; d >= min(dep,2) ; --d) { memset(g,0,sizeof(g)); for(int v = 1 ; v <= N ; ++v) { if(fa[v] == u) { for(int j = M ; j >= 0 ; --j) { for(int k = j ; k >= 0 ; --k) { g[j] = max(g[j],g[k] + max(f[v][j - k][d + 1],f[v][j - k][1])); } } } } for(int j = 0 ; j <= M ; ++j) f[u][j][d] = g[j] + C[u] * K[d]; } if(!nouse[u] && fa[u] != 1) { memset(g,0,sizeof(g)); for(int v = 1 ; v <= N ; ++v) { if(fa[v] == u) { for(int j = M ; j >= 0 ; --j) { for(int k = j; k >= 0 ; --k) { g[j] = max(g[j],g[k] + max(f[v][j - k][2],f[v][j - k][1])); } } } } for(int j = 0 ; j < M ; ++j) f[u][j + 1][1] = g[j] + C[u] * K[1]; } } void Init() { read(N);read(M);scanf("%lf",&K[1]); for(int i = 1 ; i <= N ; ++i) { read(fa[i]); } K[0] = 1; for(int i = 2 ; i <= N ; ++i) { K[i] = K[i - 1] * K[1]; } for(int i = 1 ; i <= N ; ++i) { scanf("%lf",&C[i]); } } void Solve() { int p = 1; db ans = 0; for(int len = 2 ; len ; ++len) { p = fa[p]; if(p == 1) break; memset(nouse,0,sizeof(nouse)); int t = 1,l = 0; while(l != len) { nouse[t] = 1; t = fa[t]; ++l; } int rec = 0; if(fa[p] != 1) {--M;rec = fa[p];fa[p] = 1;} memset(f,0,sizeof(f)); dfs(1,0); db res = f[1][M][0] / (1 - K[len]); ans = max(ans,res); if(rec) {++M;fa[p] = rec;} } printf("%.2lf\n",ans); } int main(){ #ifdef ivorysi freopen("f1.in","r",stdin); #endif Init(); Solve(); }