hdu5242 上海邀请赛 优先队列+贪心

题意是给你一棵树    n个点 n-1条边   起点是1   每个点都有权值 每次能从根节点走到叶子节点   经行k次游戏 每次都是从1开始    拿过的点的权值不能拿第二次   问最大权值和;

开始看到题时也没想到什么方法  就按照常规的来  结果超时了   试着优化了好多次  最后过了   百度题解说是树链剖分    醉了    还没学!!!

说说我的做法吧    map【i】=a表示i节点的跟节点为a节点   从所有叶子节点开始入队(有点队列里有三个变量  分别是节点编号  权值  深度  优先级看代码    里面有点贪心的意思) 每次走根节点   如果根节点没走过  则走它   并把该店权值变为0    否则直接跳到1这个节点(如果一个个跳可能会超时)再入队    当出队的编号为1时并且拿的个数小于游戏次数 则拿  否则结束  在跑深度的时候有个优化
    开始没有超时了            如果该节点深度已知了  则以后的根节点就不用跑了!!!  具体看代码吧

#include<stdio.h>
#include<string.h>
#include<queue>
#include<iostream>
using namespace std;

int map[100010],mark[100010];
int Deep[100010];
__int64 num[100010];
struct node
{
    __int64 value;
    int ii;
    int deep;
    bool operator < (const node& x) const
    {
        return deep<x.deep||(deep==x.deep&&value<x.value);
    }
}a;
int main()
{
    int T,i,j,n,k,r=1;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&k);
        for(i=1;i<=n;i++)
        {
            scanf("%I64d",&num[i]);
        }
        memset(mark,0,sizeof(mark));
        for(i=1;i<n;i++)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            mark[x]=1;
            map[y]=x;
        }
        priority_queue<node>Q;
        memset(Deep,0,sizeof(Deep));
        for(i=1;i<=n;i++)
        {
            if(mark[i]==0)
            {
                int x=map[i];
                int d=1;
                while(x!=1)
                {
                    if(Deep[x]>0) {d+=Deep[x];break;}
                    x=map[x];
                    d++;
                }
                x=i;
                while(x!=1)
                {
                    if(Deep[x]>0) break;
                    Deep[x]=d;
                    x=map[x];
                    d--;
                }
                a.deep=Deep[i];
                a.value=num[i];
                a.ii=i;
                Q.push(a);

            }
        }
        //for(i=1;i<=n;i++)
        //printf("%d ^^^ %d\n",i,Deep[i]);
        __int64 sum=0;
        int cont=0;
        while(!Q.empty())
        {
            a=Q.top();
            Q.pop();
            int x=map[a.ii];
            /*while(num[x]==0&&x!=1)
            {
                x=map[x];
            }*/
            if(a.ii==1)
            {
                a.value+=num[1];
                num[1]=0;
                sum+=a.value;
                cont++;
                if(cont>=k) break;
            }
            else
            {
                if(num[x]==0)
                {
                    a.ii=1;
                    a.deep=0;
                }
                else
                {
                    a.ii=x;
                    a.deep=Deep[x];
                    a.value+=num[x];
                    num[x]=0;
                }
                Q.push(a);
            }
        }
        printf("Case #%d: %I64d\n",r++,sum);
    }
    return 0;
}
时间: 2024-12-11 03:21:26

hdu5242 上海邀请赛 优先队列+贪心的相关文章

上海邀请赛之热身赛2_2013成都邀请赛

先写总结. 感觉这次跟scf和sjc组队有种瞬间碉堡了的感觉,虽然是临时组建的队伍凑齐准备去上海参加邀请赛,从这次比赛磨练配合. 今天比赛难度比前天那次的难度低,感觉更适合我们来练习. 话说好像比赛提早了5分钟,我们三个人都不知道,五分钟后一看A题学长已经A了,一想肯定特水...我就没看题,sjc和scf两个看了题,scf就开始敲了,我刚开始负责翻译题,虽然我英语是个渣渣...没办法,没翻译他们几乎做不出题...我就没做题,翻译了B和G.scf敲了貌似好久才完成(赛后重做,特水,基本3分钟就可以

hdu 4544 湫湫系列故事——消灭兔子 优先队列+贪心

将兔子的血量从小到大排序,箭的威力也从小到大排序, 对于每只兔子将威力大于血量的箭加入队列,写个优先队列使得出来数位价钱最少.. #include<stdio.h> #include<queue> #include<algorithm> #include<iostream> #include<functional> using namespace std; const int maxn=100010; struct tt { int d; int

[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

A Computer Graphics Problem 4176 2013上海邀请赛

A Computer Graphics Problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 968    Accepted Submission(s): 688 Problem Description In this problem we talk about the study of Computer Graphics.

ZOJ-3410Layton&#39;s Escape(优先队列+贪心)

Layton's Escape Time Limit: 2 Seconds      Memory Limit: 65536 KB Professor Layton is a renowned archaeologist from London's Gressenheller University. He and his apprentice Luke has solved various mysteries in different places. Unfortunately, Layton

2015上海邀请赛

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

hdu 2850 Load Balancing (优先队列 + 贪心)

题目大意: 怎么分配n个任务到m个服务器上使得负载尽量平衡. 思路: 将任务从大到小排序,依次放入负载最小的那个服务器中. 因为是spj 的缘故,所以可以使用这个贪心. 比如数据 6 2 7 5 3 3 3 3 就会得到错误答案. #include <cstdio> #include <iostream> #include <algorithm> #include <cstring> #include <queue> using namespac

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

hdu 4544 优先队列+贪心

题意:最近,减肥失败的湫湫为发泄心中郁闷,在玩一个消灭免子的游戏.游戏规则很简单,用箭杀死免子即可.箭是一种消耗品,已知有M种不同类型的箭可以选择,并且每种箭都会对兔子造成伤害,对应的伤害值分别为Di(1 <= i <= M),每种箭需要一定的QQ币购买.假设每种箭只能使用一次,每只免子也只能被射一次,请计算要消灭地图上的所有兔子最少需要的QQ币. 链接:点我 贪心在能杀死某个兔子的箭里选择价格最小的 一开始直接两个for,tle,看了别人代码之后才知道用优先队列 1 #include<