I - Apple Tree 树形dp
const LL INF = 100000000000000; const double eps = 1e-8; const int maxn = 300100; LL v[maxn]; vector<int> g[maxn]; vector<int> G[maxn]; LL dp[maxn]; LL ans; LL leaf[maxn]; LL gcd(LL x,LL y) { return y == 0 ? x : gcd(y,x%y); } LL lcm(LL x,LL y) { return x/gcd(x,y)*y; } bool flag; LL dfs(int x) { if(flag == false) return -1;//1 if(dp[x] != -1) return dp[x]; LL sum = 0; LL LCM; if(g[x].size() == 0)//2 LCM = 1; else LCM = leaf[x]/g[x].size(); LL Min = INF; rep(i,0,g[x].size()) { if(g[x][i] == x) continue; Min = min(Min,dfs(g[x][i])); } rep(i,0,g[x].size()) { if(g[x][i] == x) continue; sum += dp[g[x][i]]; } if(Min < LCM) {//3 flag = false; return -1; } Min = Min - Min%LCM; dp[x] = g[x].size()*Min; ans += sum - dp[x]; if(dp[x] < leaf[x])//4 { flag = false; return -1; } return dp[x]; } bool vis[maxn]; void dfs1(int x) { rep(i,0,G[x].size()) { if(!vis[G[x][i]]) { g[x].push_back(G[x][i]); vis[G[x][i]] = true; dfs1(G[x][i]); } } } LL dfs2(int x) { if(leaf[x]) return leaf[x]; if(g[x].size() == 0) { leaf[x] = 1; return 1; } LL LCM = 1; rep(i,0,g[x].size()) { if(g[x][i] == x) continue; LL T = dfs2(g[x][i]); LCM = lcm(LCM,T); } leaf[x] = LCM*g[x].size(); return leaf[x]; } int main() { //freopen("in.txt","r",stdin); int n; while(cin>>n) { clr(leaf); repf(i,1,n) dp[i] = -1; LL SUM = 0; repf(i,1,n) { scanf("%I64d",&v[i]); SUM += v[i]; if(v[i]) dp[i] = v[i],leaf[i] = 1; } repf(i,1,n-1) { int a,b; scanf("%d%d",&a,&b); G[a].push_back(b); G[b].push_back(a); } ans = 0; clr(vis); vis[1] = 1; flag = true; dfs1(1); dfs2(1); dfs(1); if(flag == false) cout<<SUM<<endl; else cout<<ans<<endl; } return 0; }
posted on 2013-11-29 20:44 keep trying 阅读(214) 评论(0) 编辑 收藏 举报