2019 Multi-University Training Contest 8 - 1006 - Acesrc and
发布时间:2020-12-13 21:32:53 所属栏目:PHP教程 来源:网络整理
导读:http://acm.hdu.edu.cn/showproblem.php?pid=6662 仿照 CC B - TREE 那道题的思路写的,差不多。也是要走路径。 像这两种必须走到叶子的路径感觉是必须从INF出发,使得它强制从子树转移过来。否则假如可以在中间节点中断的话,初始值就是0,转移的时候假如子
http://acm.hdu.edu.cn/showproblem.php?pid=6662 像这两种必须走到叶子的路径感觉是必须从INF出发,使得它强制从子树转移过来。否则假如可以在中间节点中断的话,初始值就是0,转移的时候假如子树更不好就不会更新这个0。 f[u]表示从u节点向下走向子树的最优值,这样必须dfs到叶子然后初始化叶子再返回。 这样子定义导致在统计答案的时候要特判。 #include<bits/stdc++.h> using namespace std; typedef long long ll; const int MAXN = 1e5 + 5; ll val[MAXN]; vector<int> E[MAXN]; int ROOT; void dfs1(int u,int p) { if(E[u].size() == 1) { ROOT = u; return; } for(auto v : E[u]) { if(v == p) continue; dfs1(v,u); if(ROOT != -1) return; } } const ll INF = 1e18 + 1e17; const ll INF2 = 1e16; struct F { ll val; int son; } fm1[MAXN],fm2[MAXN],fM1[MAXN],fM2[MAXN],tmpm,tmpM; inline void InitF(int n) { for(int i = 1; i <= n; ++i) { fm1[i].val = fm2[i].val = INF; fM1[i].val = fM2[i].val = -INF; fm1[i].son = fm2[i].son = fM1[i].son = fM2[i].son = -1; } } void maintainF(int u,int v) { if(tmpM.val < fm2[u].val) { fm2[u] = tmpM; fm2[u].son = v; if(fm2[u].val < fm1[u].val) { swap(fm1[u],fm2[u]); } } if(tmpm.val > fM2[u].val) { fM2[u] = tmpm; fM2[u].son = v; if(fM2[u].val > fM1[u].val) { swap(fM1[u],fM2[u]); } } } void dfsF(int u,int p) { if(E[u].size() == 1 && E[u][0] == p) { fm1[u].val = val[u]; fM1[u].val = val[u]; fm1[u].son = u; fM1[u].son = u; return; } for(auto v : E[u]) { if(v == p) continue; dfsF(v,u); tmpM = fM1[v]; tmpm = fm1[v]; maintainF(u,v); } fm1[u].val += val[u]; fm2[u].val += val[u]; fM1[u].val += val[u]; fM2[u].val += val[u]; } struct G { ll val; } gm[MAXN],gM[MAXN]; inline void InitG(int n) { for(int i = 1; i <= n; ++i) { gm[i].val = INF; gM[i].val = -INF; } } F getFm(int u,int p) { if(fm1[p].son == u) return fm2[p]; return fm1[p]; } F getFM(int u,int p) { if(fM1[p].son == u) return fM2[p]; return fM1[p]; } void maintainG(int u,int p) { if(p == -1) { gm[u].val = val[u]; gM[u].val = val[u]; return; } gm[u].val = max(getFM(u,p).val,gM[p].val) + val[u]; gM[u].val = min(getFm(u,gm[p].val) + val[u]; } void dfsG(int u,int p) { maintainG(u,p); for(auto v : E[u]) { if(v == p) continue; dfsG(v,u); } } int main() { #ifdef Yinku freopen("Yinku.in","r",stdin); #endif // Yinku int T; scanf("%d",&T); while(T--) { int n; scanf("%d",&n); for(int i = 1; i <= n; ++i) scanf("%lld",&val[i]); for(int i = 1,b; i <= n; ++i) { scanf("%d",&b); val[i] -= b; } for(int i = 1; i <= n; ++i) E[i].clear(); for(int i = 1; i <= n - 1; ++i) { int u,v; scanf("%d%d",&u,&v); E[u].push_back(v); E[v].push_back(u); } ROOT = -1; dfs1(1,-1); //ROOT是其中一个叶子 InitF(n); dfsF(ROOT,-1); InitG(n); dfsG(ROOT,-1); ll ans = -INF; for(int i = 1; i <= n; ++i) { ll tmp = (E[i].size() == 1 && i != ROOT ? INF : fm1[i].val); tmp = min(tmp,(i != ROOT) ? (gm[i].val) : INF); ans = max(ans,tmp); } printf("%lldn",ans); } return 0; } 假如定义f和g不包含节点本身的话,那是不是不需要特判呢?只能说是判得更恶心了。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |