zoukankan      html  css  js  c++  java
  • 2020 Multi-University Training Contest 5 Tree (树形DP)

    题目

    Problem Description
    Aphelios likes to play with tree. A weighted tree is an undirected connected graph without cycles and each edge has a weight. The degree of each vertex is the number of vertexes which connect with it. Now Aphelios has a weighted tree T with n vertex and an integer k, and now he wants to find a subgraph G of the tree, which satisfies the following conditions:

    1. G should be a connected graph, in other words, each vertex can reach any other vertex in the subgraph G.

    2. the number of the vertex whose degree is larger than k is no more than 1.

    3. the total weight of the subgraph is as large as possiblie.

    Now output the maximum total weight of the subgraph you can find.

    Input
    The first line contains an integer q, which represents the number of test cases.

    For each test case, the first line contains two integer n and k (1≤n≤2×105,0≤k<n).

    For next n−1 lines , each line contains 3 numbers u,v,d, which means that there is an edge between u and v weighted d (1≤u,v≤n,0≤d≤109).

    You may assume that ∑n≤106.

    Output
    For each test case, output one line containing a single integer ans denoting the total weight of the subgraph.

    Sample Input
    1
    5 2
    1 2 5
    2 3 2
    2 4 3
    2 5 4

    Sample Output
    14

    思路

    代码实现 (RE代码,没调出来)

    #include<cstdio>
    #include<algorithm>
    #include<vector>
    #include<queue>
    #include<map>
    #include<functional>
    #include<iostream>
    #include<cstring>
    #include<cmath>
    using namespace std;
    #define rep(i,f_start,f_end) for (int i=f_start;i<=f_end;++i)
    #define per(i,n,a) for (int i=n;i>=a;i--)
    #define MT(x,i) memset(x,i,sizeof(x) )
    #define rev(i,start,end) for (int i=0;i<end;i++)
    #define inf 0x3f3f3f3f
    #define mp(x,y) make_pair(x,y)
    #define lowbit(x) (x&-x)
    #define MOD 1000000007
    #define exp 1e-8
    #define N 1000005 
    #define fi first 
    #define se second
    #define pb push_back
    typedef long long ll;
    typedef pair<ll ,ll> PII;
    typedef pair<int ,PII> PIII;
    ll gcd (ll a,ll b) {return b?gcd (b,a%b):a; }
    inline int read() {
        char ch=getchar(); int x=0, f=1;
        while(ch<'0'||ch>'9') {
            if(ch=='-') f = -1;
            ch=getchar();
        } 
        while('0'<=ch&&ch<='9') {
            x=x*10+ch-'0';
            ch=getchar();
        }   return x*f;
    }
    
    const int maxn=4e5+5;
    ll dp[maxn][2];
    vector <PII> G[maxn];
    int t;
    
    int main () {
        ios::sync_with_stdio (false);
        cin>>t;
        while (t--) {
            int n,k;
            scanf ("%d%d",&n,&k);
            int u,v,w;
            rep (i,1,n) G[i].resize (0);
    
            rep (i,1,n-1) {
                scanf ("%d%d%d",&u,&v,&w);
                G[u].pb (mp (v,w));
                G[v].pb (mp (u,w));
            }
            if (k==0) {
                puts ("0");
                cout<<endl;
                continue;
            }
            ll ans=0;
            function<void(int, int)> dfs;
            dfs = [&](int now,int fa) {
                dp[now][0]=dp[now][1]=0;
                int all=0;
                vector <PII> a;
                a.push_back (make_pair (0,0));
                for (auto it :G[now]) {
                    if (it.first==fa) continue;
                    dfs (it.first,now);
                    a.pb (mp (it.second+dp[it.first][0],it.second+dp[it.first][1]));
                    all++;
                }
                ll ansl=0,ansr=0;
                sort (a.begin()+1,a.begin()+1+all,
                       [](const PII &a,const PII &b) {return a.first>b.first; } );
                rep (i,1,min (k-1,all)) dp[now][0]+=a[i].first;
                if (all>=k) ansl=dp[now][0]+a[k].first;
                else ansl=dp[now][0];
                ans=max (ans,ansl);
                
                rep (i,1,all) dp[now][1]+=a[i].first;
                ansr=dp[now][1];
                rep (i,1,min (all,k-1)) 
                   dp[now][1]=
                   max (dp[now][1],dp[now][0]-a[i].first+a[i].second);
                for (int i=k;i<=all&&(k-1)>0;i++) 
                   dp[now][1]=
                   max (dp[now][1],dp[now][0]-a[k-1].first+a[i].second);
                rep (i,1,min (k,all)) 
                  ansr=max (ansr,ansl-a[i].first+a[i].second);
                for (int i=k+1;i<=all&&(k>0);i++) 
                  ansr=max (ansr,ansl-a[k].first+a[i].second);
                ans= max (ansr,ans);
            };
            dfs (1,0);
            cout<<ans<<endl;
        }
    
        return 0;
    }
    
  • 相关阅读:
    LuoguP1016 旅行家的预算 (贪心)
    LuoguP2254 [NOI2005]瑰丽华尔兹 (单调队列优化DP)(用记忆化过了。。。)
    LuoguP2876 [USACO07JAN]解决问题Problem Solving (区间DP)(未完成)
    Luogu3275 [SCOI2011]糖果 (差分约束)
    Luogu1993 小K的农场 (差分约束)
    Luogu4427 [BJOI2018]求和 (树上差分)
    LuoguP1516 青蛙的约会 (Exgcd)
    POJ3903Stock Exchange (LIS)
    LuoguP1020 导弹拦截 (LIS)
    线性筛
  • 原文地址:https://www.cnblogs.com/hhlya/p/13449758.html
Copyright © 2011-2022 走看看