• 2019ICPC银川网络赛 G. Factories (gym102222 G)


    其实主要是想存一下这个读入挂。。做法的话很明显 N*100*100的树背包,主要是儿子向父亲的转移,然后正确想法是考虑边的贡献,往上转移时这条边的贡献就是(k-j)*j*w,就是它子树内的工厂和外面的。然后要注意特判n=2 n=1  k=1的情况就好了。

    #include<bits/stdc++.h>
    #define pb push_back
    #define ll long long
    #define mp make_pair
    #define _min(x,y) (x>=y?y:x)
    using namespace std;
    const int N=1e5+7;
    const int M=720;
    const ll inf=1e18;
    inline char nc(){
        static char buf[100000],*begin=buf,*end=buf;
        if(begin==end)begin=buf,end=buf+fread(buf,1,100000,stdin);
        if(begin==end)return EOF;
        return *begin++;
    }
    template<typename T>
    inline bool read(T &x){
        char c=nc();
        if(c==EOF)return false;
        x=0;
        while(!(c>='0'&&c<='9'||c=='-'))c=nc();
        bool flag=c=='-'?(c=nc(),1):0;
        while(c>='0'&&c<='9')x=x*10+c-'0',c=nc();
        if(flag)x=-x;
        return true;
    }
    int T;
    int n,m,k;
    ll dp[N][105];
    int cnt;
    int fir[N],nxt[N*2],to[N*2];
    ll val[N*2];
    void add_e(int x,int y,ll w){
        ++cnt;nxt[cnt]=fir[x];fir[x]=cnt;to[cnt]=y;val[cnt]=w;
        ++cnt;nxt[cnt]=fir[y];fir[y]=cnt;to[cnt]=x;val[cnt]=w;
    }
    int u,v,w;
    int du[N];
    int lef[N];
    void dfs(int x,int fa){
        //cout<<x<<"
    ";
        if(du[x]==1){
            dp[x][0]=dp[x][1]=0;
            lef[x]=1;
            return;
        }
        dp[x][0]=0;
        lef[x]=0;
        for(int i=1;i<=k;i++)dp[x][i]=inf;
        for(int i=fir[x];i;i=nxt[i]){
            int v=to[i];if(v==fa)continue;
            dfs(v,x);
            lef[x]+=lef[v];
            ll qw=val[i];
            int pq=min(lef[v],k);
            for(int r=_min(lef[x],k);r>=0;r--){
                for(int j=0;j<=pq&&j<=r;j++){
                    dp[x][r]=_min(dp[x][r],dp[x][r-j]+dp[v][j]+(k-j)*j*qw);
                }
            }
        }
    
    
    }
    void init(){
        fill(fir+1,fir+1+n,0);
        fill(du+1,du+1+n,0);
        //for(int i=1;i<=n;i++)fir[i]=du[i]=lef[i]=0;
        cnt=0;
    }
    int main(){
        read(T);
        int cas=0;
        while(T--){
            read(n);read(k);init();
            for(int i=1;i<n;i++){
                read(u);read(v);read(w);
                add_e(u,v,w);
                du[u]++;du[v]++;
            }
            cout<<"Case #"<<++cas<<": ";
            if(n==1||k==1){
                cout<<0<<"
    ";
                continue;
            }
            if(n==2){
                cout<<w<<"
    ";
                continue;
            }
            int st=0;
            for(int i=1;i<=n;i++){
                if(du[i]!=1){st=i;break;}
            }
            dfs(st,0);
            cout<<dp[st][k]<<"
    ";
        }
    }
    

      

  • 相关阅读:
    2. 两数相加
    1. 两数之和
    x-pack elasticsearch
    简单的文档
    PHP imagepng函数 问题
    Nginx 配置
    nginx内置变量
    TCP通信
    mysql 的一些操作
    ubuntu 软件包降级
  • 原文地址:https://www.cnblogs.com/intwentieth/p/11459249.html
Copyright © 2020-2023  润新知