HDU 5242 GAME 2015上海邀请赛G题

题目链接:hdu 5242

题意:给定一颗以1号节点为根节点的有向树,每个节点有一个权值,问从1号节点出发k次,能到达的所有节点的和的最大值。

思路:贪心的把树的链按照权值和从大到小剖分成若干条链(过程可以根据上交书上的熟练剖分模版做细小改动),然后根据每条链的权值排序取最大的k个就是答案。

代码:

#include <cstdio>
#include <cmath>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn =100000+5;
const int maxm=maxn+maxn;
int v[maxm],info[maxn],Prev[maxm],Q[maxn],dep[maxn];
int belong[maxn],head[maxn];
long long size[maxn];
bool vis[maxn];
int cnt=0,N,nedge=0;
int weight[maxn];
inline void insert(int x,int y){
    ++nedge;
    v[nedge]=y;Prev[nedge]=info[x];info[x]=nedge;
}
void split(){
    int l,r;
    memset(dep,-1,sizeof(dep));
    l=0;
    dep[Q[r=1]=1]=0;
    while(l<r){
        int x=Q[++l];
        vis[x]=false;
        for(int y=info[x];y!=-1;y=Prev[y]){
            if(dep[v[y]]==-1){
                dep[Q[++r]=v[y]]=dep[x]+1;
            }
        }
    }
    for(int i=N;i;i--){
        int x=Q[i],p=-1;
        size[x]=weight[x];
        for(int y=info[x];y!=-1;y=Prev[y]){
            if(vis[v[y]]){
                if(p==-1||size[v[y]]>size[p])
                    p=v[y];
            }
        }
        if(p==-1){
            ++cnt;
            belong[head[cnt]=x]=cnt;
        }
        else {
            size[x]+=size[p];
            belong[x]=belong[p];
            head[belong[x]]=x;
        }
        vis[x]=true;
    }

}
bool cmp(int a,int b){
    return size[head[a]]>size[head[b]];
}
int ans[maxn];
long long get_ans(int k){
    long long ret=0;
    for(int i=1;i<=cnt;i++) ans[i]=i;
    sort(ans+1,ans+cnt+1,cmp);
    for(int i=1;i<=min(cnt,k);i++){
        ret+=size[head[ans[i]]];
    }
    return ret;
}
int main(){
    int k,a,b,T,cas=0;
    //freopen("data.in","r",stdin);
    scanf("%d",&T);
    while(T--){
        printf("Case #%d: ",++cas);
        scanf("%d%d",&N,&k);
        memset(info,-1,sizeof(info));
        cnt=0;nedge=0;
        for(int i=1;i<=N;i++){
            scanf("%d",weight+i);
        }
        for(int i=1;i<N;i++){
            scanf("%d%d",&a,&b);
            insert(a,b);
        }
        split();
        cout<<get_ans(k)<<endl;
    }
    return 0;
}
时间: 2024-10-12 22:49:38

HDU 5242 GAME 2015上海邀请赛G题的相关文章

2015上海邀请赛

这次上海邀请赛差一点就能拿到牌子了,好可惜..... Game回来写了下,刚开始把重链写成了最大权子树,无限WA,然后一直在调..... 发现我一旦提交上去错了就始终在找程序BUG,从来没想过是不是思路哪里错掉了....其实这种交上去WA之后应该先去找思路上的错误,而不是怀疑题目有陷阱什么的... #include<stdio.h> #include<string.h> #include<vector> #include<list> #include<

HDU 5242 上海大都会 G题

这道题其实是求K条最长的不重叠的链.贪心算法+DFS即可求.深度优先搜索时,返回当前子树的最长链,使用优先队列保存其他孩子结点的最长链,即可.求结果时只需从优先队列中取前K个值的和.这相当于暴力删除每条最长的链. #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <queue> #define LL long long us

HDOJ Page Rank 5097【2014上海邀请赛H题-简单矩阵】

Page Rank Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 100000/100000 K (Java/Others) Total Submission(s): 282    Accepted Submission(s): 77 Problem Description Evaluation and rank of web pages is a hot topic for many internet companies and

HDU 5093Battle ships(2014上海邀请赛)

题目: Battle ships Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 477    Accepted Submission(s): 197 Problem Description Dear contestant, now you are an excellent navy commander, who is responsi

上海邀请赛 补题中

比赛的时候就出了5题,赛后发现其实很多题可以写,不知道为啥赛时这么逗比加坑队友,过两天做个总结 5236 Article 29.45%(134/455) 5237 Base64 41.67%(175/420)   5238 Calculator 43.85%(82/187) 5239 Doom 23.67%(138/583) 5240 Exam 50.61%(249/492) 5241 Friends 48.86%(215/440) 5242 Game 29.91%(195/652) 5243

[java线段树]2015上海邀请赛 D Doom

题意:n个数 m个询问 每个询问[l, r]的和, 再把[l, r]之间所有的数变为平方(模为9223372034707292160LL) 很明显的线段树 看到这个模(LLONG_MAX为9223372036854775807) 很明显平方时会爆LL 很容易发现所有数平方模了几次之后值就不再改变了 而且这个“几次”相当小 因此直接暴力搞就好了 public static void main(String[] args) { Scanner in = new Scanner(System.in);

[java]2015上海邀请赛 B Base64

题意: 给n和一个字符串(可以有空格) 求字符串编码n次后的字符串 编码方式:字符串的每个字符转化成ASCII码, ASCII码转化成8位2进制,    将二进制数分割成6位为一组的(不够的补0), 再变成十进制数 依次按照以下方式变成字母 转化成字母后, 若长度不是4的整数倍, 在字符串后面补= 举个例子, The的ASCII码分别为84,104,101 转成8位2进制为01010100,01101000,01100101 分割成6位的为010101,000110,100001,100101

[POI 2001+2014acm上海邀请赛]Gold Mine/Beam Cannon 线段树+扫描线

Description Byteman, one of the most deserving employee of The Goldmine of Byteland, is about to retire by the end of the year. The Goldmine management would like to reward him in acknowledgment of his conscientious work. As a reward Byteman may rece

hdu 4587 2013南京邀请赛B题/ / 求割点后连通分量数变形。

题意:求一个无向图的,去掉两个不同的点后最多有几个连通分量. 思路:枚举每个点,假设去掉该点,然后对图求割点后连通分量数,更新最大的即可.算法相对简单,但是注意几个细节: 1:原图可能不连通. 2:有的连通分量只有一个点,当舍去该点时候,连通分量-1: 复习求割点的好题! #include<iostream> #include<cstdio> #include<vector> using namespace std; int n,m; vector<vector&