348B - Apple Tree 树形DP(好题
赛中没调出来。。但很早就想出lcm的正解还是挺开心的。。
1/22的提交,调了2小时,先是遇到各种爆long long的问题,最后的问题是邻接表处理子结点没完全处理好
#include<bits/stdc++.h> #include<stdio.h> #include<algorithm> #include<queue> #include<string.h> #include<iostream> #include<math.h> #include<set> #include<map> #include<vector> #include<iomanip> using namespace std; #define ll long long #define ld long double #define pb push_back #define FOR(a) for(int i=1;i<=a;i++) const int inf=0x3f3f3f3f; const long long Linf=9e18; const int maxn=1e5+9; int n; vector<int>G[maxn]; ll weight[maxn]; ll ans=0; int flag; ll g[maxn]; //g[u]表示u节点的份尺寸 ll gcd(ll a,ll b){ return b==0?a:gcd(b,a%b); } ll lcm(ll a,ll b){ return a/gcd(a,b)*b; } void dfs(int u,int fa){ if(flag==9)return; int sz=G[u].size(); if(u!=1 && sz==1){ return; } ll minn=Linf; for(int i=0;i<sz;i++){ int v=G[u][i];if(v==fa)continue; dfs(v,u); if(flag==9)return; minn=min(minn,weight[v]); g[u]=lcm(g[u],g[v]); if(g[u]>minn){ flag=9;return; } } ll nx;if(u==1)nx=G[u].size(); else nx=G[u].size()-1; //ll minus=minn%g[u]; ll minus=minn-(minn/g[u])*g[u]; if(minus==minn){ flag=9;return; } g[u]*=nx; minn-=minus; /* for(int i=0;i<sz;i++){ int v=G[u][i];if(v==fa)continue; ans+=weight[v]-minn; weight[v]=minn; } */ weight[u]=minn*(nx); } int main(){ scanf("%d",&n); FOR(n)g[i]=1; ll cnt=0; FOR(n){scanf("%lld",&weight[i]);cnt+=weight[i];} FOR(n-1){ int u,v; scanf("%d%d",&u,&v); G[u].pb(v); G[v].pb(u); } flag=0; dfs(1,1); if(flag==9){ printf("%lld\n",cnt);return 0; } printf("%lld\n",cnt-weight[1]); }