zoukankan      html  css  js  c++  java
  • codeforces 671D

    这题真神了……没想到链的问题还可以转化为子树解……一开始总以为是树链剖分……

    我们可以先把问题转化为每条边只能被一个工人修复一次,可以证明这样答案不会更优也不会更差

    设f[i]表示覆盖了i节点子树的所有边都被覆盖且i的父向边也被覆盖的最小花费

    我们可以把工人修复转化为“头加尾减”,即在u[i]处添加i个工人并在v[i]处删除这个工人

    这样我们对每个节点添加的工人工人维护dfs序,这样我们从下往上更新即可

    (注意中间计算不要爆long long)

      1 #include<bits/stdc++.h>
      2 
      3 using namespace std;
      4 typedef long long ll;
      5 int l[300010],r[300010],b[300010],c[300010],fa[300010],n,m,t;
      6 ll f[300010],tr[300010*4],laz[300010*4];
      7 vector<int> g[300010],w[300010],d[300010];
      8 
      9 const ll inf=1000000000000007ll;
     10 void inc(ll &x,ll y)
     11 {
     12     x+=y;
     13     if (x>inf) x=inf;
     14 }
     15 
     16 void push(int i)
     17 {
     18     inc(laz[i*2],laz[i]);
     19     inc(laz[i*2+1],laz[i]);
     20     inc(tr[i*2],laz[i]);
     21     inc(tr[i*2+1],laz[i]);
     22     laz[i]=0;
     23 }
     24 
     25 void change(int i,int l,int r,int x,ll y)
     26 {
     27     if (l==r) tr[i]=y;
     28     else {
     29         int m=(l+r)>>1;
     30         if (laz[i]) push(i);
     31         if (x<=m) change(i*2,l,m,x,y);
     32         else change(i*2+1,m+1,r,x,y);
     33         tr[i]=min(tr[i*2],tr[i*2+1]);
     34     }
     35 }
     36 
     37 void add(int i,int l,int r,int x,int y,ll z)
     38 {
     39     if (x<=l&&y>=r)
     40     {
     41         inc(tr[i],z);
     42         inc(laz[i],z);
     43     }
     44     else {
     45         int m=(l+r)>>1;
     46         if (laz[i]) push(i);
     47         if (x<=m) add(i*2,l,m,x,y,z);
     48         if (y>m) add(i*2+1,m+1,r,x,y,z);
     49         tr[i]=min(tr[i*2],tr[i*2+1]);
     50     }
     51 }
     52 
     53 ll ask(int i,int l,int r,int x,int y)
     54 {
     55     if (x>y) return inf;
     56     if (x<=l&&y>=r) return tr[i];
     57     else {
     58         int m=(l+r)>>1;
     59         ll s=inf;
     60         if (laz[i]) push(i);
     61         if (x<=m) s=min(s,ask(i*2,l,m,x,y));
     62         if (y>m) s=min(s,ask(i*2+1,m+1,r,x,y));
     63         return s;
     64     }
     65 }
     66 
     67 
     68 void dfs(int x)
     69 {
     70     l[x]=t+1;
     71     for (int i=0; i<w[x].size(); i++) b[w[x][i]]=++t;
     72     for (int i=0; i<g[x].size(); i++)
     73     {
     74         int y=g[x][i];
     75         if (fa[x]!=y)
     76         {
     77             fa[y]=x;
     78             dfs(y);
     79         }
     80     }
     81     r[x]=t;
     82 }
     83 
     84 void dp(int x)
     85 {
     86     ll s=0;
     87     for (int i=0; i<g[x].size(); i++)
     88     {
     89         int y=g[x][i];
     90         if (y!=fa[x])
     91         {
     92             dp(y);
     93             inc(s,f[y]);
     94         }
     95     }
     96     if (x==1) {f[1]=s; return;}
     97     for (int i=0; i<w[x].size(); i++)
     98     {
     99         int y=w[x][i];
    100         change(1,1,m,b[y],s+(ll)c[y]);
    101     }
    102     for (int i=0; i<d[x].size(); i++)
    103     {
    104         int y=d[x][i];
    105         change(1,1,m,b[y],inf);
    106     }
    107     for (int i=0; i<g[x].size(); i++)
    108     {
    109         int y=g[x][i];
    110         if (fa[x]!=y)
    111             add(1,1,m,l[y],r[y],s-f[y]);
    112     }
    113     f[x]=ask(1,1,m,l[x],r[x]);
    114 }
    115 
    116 
    117 int main()
    118 {
    119     scanf("%d%d",&n,&m);
    120     for (int i=1; i<n; i++)
    121     {
    122         int x,y;
    123         scanf("%d%d",&x,&y);
    124         g[x].push_back(y);
    125         g[y].push_back(x);
    126     }
    127     for (int i=1; i<=4*m; i++) {tr[i]=inf;laz[i]=0;}
    128     for (int i=1; i<=m; i++)
    129     {
    130         int x,y;
    131         scanf("%d%d%d",&x,&y,&c[i]);
    132         w[x].push_back(i);
    133         d[y].push_back(i);
    134     }
    135     t=0; dfs(1);
    136     dp(1);
    137     if (f[1]>=inf) puts("-1"); else printf("%lld
    ",f[1]);
    138 }
    View Code
  • 相关阅读:
    软件测试
    软件测试
    软件测试
    软件测试
    软件测试
    软件测试
    软件测试
    软件测试
    软件测试
    When:什么时候做集成测试
  • 原文地址:https://www.cnblogs.com/phile/p/6355057.html
Copyright © 2011-2022 走看看