1147 - 最后你还是AK了

Time Limit:5s Memory Limit:256MByte

DESCRIPTION

今天n/2对点的距离求和,我们将所有匹配方案里距离和最大的那一个值定义为可爱值.

即我们将这

定义y的距离,那么可爱值为

max(∑i=1n/2dis(ai,bi))

现在HH想知道使用了膜法以后,这颗树的可爱值最多能是多少.

INPUT
第一行是一个整数T组数据 对于每组数据输入一行2个整数k次膜法. 接着一行w的边. 最后一行ci 保证n为偶数且给出的是一颗树
OUTPUT
每组数据输出一行,一个整数,表示♂可♂爱♂值♂最多能是多少
SAMPLE INPUT
1 4 2 1 2 5 2 3 5 3 4 5 5 5
SAMPLE OUTPUT
35
HINT
对于样例,我们将1和4匹配,2和3匹配,然后对2和3之间的边使用膜法,对3和4之间的边使用魔法 若出现爆栈问题,改栈方法请参考1093题目代码 1093地址:http://www.ifrog.cc/acm/problem/1093 代码地址:http://ideone.com/Wk24ET
分析:不考虑加魔法时与加魔法是独立的;
   不加魔法时贪心的对每条边算贡献为min(son[x] , n - son[x] )*len ,可以想象一下是可行的;
   加入魔法时只需贪心的放min(son[x] , n - son[x] )大的边即可;
代码:
#define OPENSTACK
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <climits>
#include <cstring>
#include <string>
#include <set>
#include <bitset>
#include <map>
#include <queue>
#include <stack>
#include <vector>
#include <cassert>
#include <ctime>
#define rep(i,m,n) for(i=m;i<=(int)n;i++)
#define mod 1000000007
#define inf 0x3f3f3f3f
#define vi vector<int>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define ll long long
#define pi acos(-1.0)
#define pii pair<int,int>
#define sys system("pause")
#define ls rt<<1
#define rs rt<<1|1
const int maxn=1e5+10;
const int N=5e2+10;
using namespace std;
ll gcd(ll p,ll q){return q==0?p:gcd(q,p%q);}
ll qmul(ll p,ll q,ll mo){ll f=0;while(q){if(q&1)f=(f+p)%mo;p=(p+p)%mo;q>>=1;}return f;}
ll qpow(ll p,ll q,ll mo){ll f=1;while(q){if(q&1)f=qmul(f,p,mo)%mo;p=qmul(p,p,mo)%mo;q>>=1;}return f;}
int n,m,k,t,son[maxn],c[maxn],id[maxn];
vi e[maxn];
vi f[maxn];
ll ret;
bool cmp(int x,int y){return min(son[x],n-son[x])>min(son[y],n-son[y]);}
void dfs(int x,int y)
{
    son[x]=1;
    int i;
    rep(i,0,e[x].size()-1)
    {
        int z=e[x][i],w=f[x][i];
        if(z==y)continue;
        dfs(z,x);
        ret+=1LL*min(son[z],n-son[z])*w;
        son[x]+=son[z];
    }
}
int main()
{
        #ifdef OPENSTACK
        int size = 64 << 20; // 64MB
        char *p = (char*)malloc(size) + size;
        #if (defined _WIN64) or (defined __unix)
            __asm__("movq %0, %%rsp\n" :: "r"(p));
        #else
            __asm__("movl %0, %%esp\n" :: "r"(p));
        #endif
    #endif
    int i,j;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&k);
        rep(i,1,n)id[i]=i,e[i].clear(),f[i].clear(),son[i]=0;
        rep(i,1,n-1)
        {
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            e[x].pb(y);
            f[x].pb(z);
            e[y].pb(x);
            f[y].pb(z);
        }
        rep(i,1,k)scanf("%d",&c[i]);
        ret=0;
        dfs(1,0);
        sort(c+1,c+k+1,greater<int>());
        sort(id+1,id+n+1,cmp);
        rep(i,1,min(n,k))ret+=1LL*min(son[id[i]],n-son[id[i]])*c[i];
        printf("%lld\n",ret);
    }
    #ifdef OPENSTACK
        exit(0);
    #else
        return 0;
    #endif
}

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-08-21
  • 2021-07-02
  • 2021-10-21
猜你喜欢
  • 2022-12-23
  • 2021-06-27
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-08-21
  • 2022-12-23
相关资源
相似解决方案