zoukankan      html  css  js  c++  java
  • cogs 2652. 秘术「天文密葬法」(0/1分数规划 长链剖分 二分答案 dp

    http://cogs.pro:8080/cogs/problem/problem.php?pid=vSXNiVegV

    题意:给个树,第i个点有两个权值ai和bi,现在求一条长度为m的路径,使得Σai/Σbi最小。

    思路:二分答案得p,把每个点权值变成ai-p*bi,看是否存在长为一条长为m的路使总和<=0。

    tag数组表示从当前位置沿最长链走到底的值,dp数组初值表示从当前位置的重儿子走到底的值(加负号),用tag[...]+dp[..]维护从当前节点往下走若干步得到的最小值(只更新dp数组

      1 # include <stdio.h>
      2 # include <string.h>
      3 # include <iostream>
      4 # include <algorithm>
      5 // # include <bits/stdc++.h>
      6 
      7 using namespace std;
      8 
      9 typedef long long ll;
     10 typedef long double ld;
     11 typedef unsigned long long ull;
     12 const int N = 3e4 + 10, M = 6e4 + 10;
     13 const int mod = 1e9+7;
     14 
     15 int n, m, A[N * 7], B[N * 7], head[N], nxt[M], to[M], tot = 0; 
     16 inline void add(int u, int v) {
     17     ++tot; nxt[tot] = head[u]; head[u] = tot; to[tot] = v;
     18 }
     19 inline void adde(int u, int v) {
     20     add(u, v), add(v, u);
     21 }
     22 
     23 int dep[N], mxd[N], son[N], sz[N]; 
     24 inline void pre_dfs(int x, int fa = 0) {
     25     dep[x] = dep[fa] + 1;
     26     mxd[x] = dep[x]; son[x] = 0;
     27     for (int i=head[x]; i; i=nxt[i]) {
     28         if(to[i] == fa) continue;
     29         pre_dfs(to[i], x);
     30         if(mxd[to[i]] > mxd[x]) mxd[x] = mxd[to[i]], son[x] = to[i];        
     31     }
     32     sz[x] = mxd[x] - dep[x]; 
     33 }
     34 
     35 int pos[N], idx; 
     36 inline void pre_pos(int x, int fa = 0) {
     37     pos[x] = ++idx;
     38     if(son[x]) pre_pos(son[x], x);
     39     for (int i=head[x]; i; i=nxt[i]) 
     40         if(to[i] != fa && to[i] != son[x]) pre_pos(to[i], x);        
     41 }
     42 
     43 double mid_check, ans;
     44 double dp[N], tag[N]; 
     45 inline void solve(int x, int fa = 0) {
     46     double *f = &dp[pos[x]], C = (double)A[x] - mid_check * B[x]; 
     47     if(son[x] == 0) {    //leaf
     48         f[0] = 0; tag[x] = C;
     49         if(m == 0) ans = min(ans, tag[x]); 
     50         return ;
     51     }
     52     solve(son[x], x); f[0] = -tag[son[x]];
     53     tag[x] = tag[son[x]] + C; 
     54     for (int i=head[x], y; i; i=nxt[i]) {
     55         if(to[i] == fa || to[i] == son[x]) continue;
     56         solve(y = to[i], x);
     57         double *g = &dp[pos[y]];
     58         for (int j=0; j<=sz[y] && j<m; ++j)
     59             if(m-1-j <= sz[x]) ans = min(ans, f[m-1-j] + tag[x] + g[j] + tag[y]); 
     60          for (int j=0; j<=sz[y]; ++j) f[j+1] = min(f[j+1], g[j] + tag[y] + C - tag[x]); 
     61     }
     62     if(m <= sz[x]) ans = min(ans, f[m] + tag[x]); 
     63 }
     64 
     65 
     66 inline bool chk(double x) {
     67      ans = 1e18; mid_check = x;
     68      solve(1); 
     69     return ans <= 0; 
     70 }
     71 
     72 int main() {
     73     freopen("cdcq_b.in", "r", stdin);
     74     freopen("cdcq_b.out", "w", stdout); 
     75     cin >> n >> m; 
     76     for (int i=1; i<=n; ++i) scanf("%d", A+i);
     77     for (int i=1; i<=n; ++i) scanf("%d", B+i);
     78     if(m == -1) {
     79         double ans = 1e18;
     80         for (int i=1; i<=n; ++i) ans = min(ans, (double)A[i]/B[i]);
     81         printf("%.2lf
    ", ans);
     82         return 0;
     83     }
     84     for (int i=1, u, v; i<n; ++i) {
     85         scanf("%d%d", &u, &v);
     86         adde(u, v);
     87     }
     88     --m;
     89     pre_dfs(1); 
     90     pre_pos(1); 
     91     double l = 0, r = 1e11, mid;
     92     while(r-l > 1e-4) {
     93         mid = (l+r)/2.0; 
     94         if(chk(mid)) r = mid;
     95         else l = mid;
     96     }
     97     if(l > 5e10) puts("-1");
     98     else printf("%.2lf
    ", l); 
     99     return 0;
    100 }
    View Code
  • 相关阅读:
    业余无线电A类考试准备笔记
    关于互联网技术基层绩效管理的一些思考
    适合产品经理的十本书 From 俞军
    从敏捷开发到微服务,maybe再到中台
    Golang内存模型
    CSS中的那点事儿(一)--- CSS中的单位2
    CSS中的那点事儿(一)--- CSS中的单位1
    design.js
    model.js
    云技术相关的概念
  • 原文地址:https://www.cnblogs.com/wzgg/p/11406298.html
Copyright © 2011-2022 走看看