• P1273 有线电视网


    题面

    https://www.luogu.org/problem/P1273

    题解

    #include<cstdio>
    #include<vector>
    #include<cstring>
    #include<iostream>
    using namespace std;
    
    int n,m,k,w[3050],v,siz[3050];
    vector<int> to[3050];
    long long f[3050][3050];
    
    struct node{
      int bro,son;
    } tree[3050];
    
    const long long inf=5e16;
    
    void maketree(int x,int fa) {
      int i,l=to[x].size(),t;
      for (i=0;i<l;i++) if (to[x][i]!=fa) {
        if (tree[x].son==0) {
          tree[x].son=to[x][i];
          maketree(to[x][i],x);
        }
        else {
          t=tree[x].son;
          while (tree[t].bro!=0) t=tree[t].bro;
          tree[t].bro=to[x][i];
          maketree(to[x][i],x);
        }
      }
    }
    
    void treesum(int x){
      if (x>=n-m+1) siz[x]=1; else siz[x]=0;
      if (tree[x].bro!=0) {
        treesum(tree[x].bro);
        siz[x]+=siz[tree[x].bro];
      }
      if (tree[x].son!=0) {
        treesum(tree[x].son);
        siz[x]+=siz[tree[x].son];
      }
    }
    
    void treedp(int x,int d){
      int i;
      long long dpl,dpr;
      if (siz[x]<d) return;
      if (f[x][d]<=inf) return;
      if (d==0) return;
      f[x][d]=inf;
      if (tree[x].bro!=0) {
        treedp(tree[x].bro,d);
        f[x][d]=min(f[x][d],f[tree[x].bro][d]);
      }
      if (x>=n-m+1) {
        for (i=0;i<=d-1;i++) {
          if (tree[x].son!=0) {
            treedp(tree[x].son,i);
            dpl=f[tree[x].son][i];
          }
          else if (i==0) dpl=0; else dpl=inf/2;
          if (tree[x].bro!=0) {
            treedp(tree[x].bro,d-1-i);
            dpr=f[tree[x].bro][d-1-i];
          }
          else if (d-1-i==0) dpr=0; else dpr=inf/2;
          if (dpl+dpr+w[x]<f[x][d]) f[x][d]=dpl+dpr+w[x];
        }
      }
      else {
        for (i=0;i<=d;i++) {
          if (tree[x].son!=0) {
            treedp(tree[x].son,i);
            dpl=f[tree[x].son][i];
          } 
          else if (i==0) dpl=0; else dpl=inf/2;
        
          if (tree[x].bro!=0) {
            treedp(tree[x].bro,d-i);
            dpr=f[tree[x].bro][d-i];
          }
          else if (d-i==0) dpr=0; else dpr=inf/2;
        
          if (dpl+dpr+w[x]<f[x][d]) f[x][d]=dpl+dpr+w[x];
        }
      }
      return;
    }
    
    int main(){
      int i,j,a,c;
      scanf("%d %d",&n,&m);
      w[1]=0;
      for (i=1;i<=n-m;i++) {
        scanf("%d",&k);
        for (j=1;j<=k;j++) {
          scanf("%d %d",&a,&c);
          w[a]=c;
          to[i].push_back(a);
        }
      }
      for (i=n-m+1;i<=n;i++) {
        scanf("%d",&v);
        w[i]-=v;
      }
      maketree(1,0);
      treesum(1);
      memset(f,1,sizeof(f));
      for (i=1;i<=n;i++) f[i][0]=0;
      for (i=m;i>=0;i--) {
        treedp(1,i);
        if (f[1][i]<=0) {
          cout<<i<<endl;
          return 0;
        }
      }
    }
  • 相关阅读:
    最后一周作业
    第十四,十五周作业
    第七周作业
    第六周作业
    第四周作业
    第三周作业
    第二周作业
    二学期第三次作业
    二学期第二次作业
    二学期第一次作业
  • 原文地址:https://www.cnblogs.com/shxnb666/p/11427450.html
Copyright © 2020-2023  润新知