hdu5242——Game(dfs贪心)

来源:互联网 发布:php 优惠券使用代码 编辑:程序博客网 时间:2024/05/19 02:26

Problem Description
It is well known that Keima Katsuragi is The Capturing God because of his exceptional skills and experience in ”capturing” virtual girls in gal games. He is able to play games simultaneously.

One day he gets a new gal game named ”XX island”. There are scenes in that game, and one scene will be transformed to different scenes by choosing different options while playing the game. All the scenes form a structure like a rooted tree such that the root is exactly the opening scene while leaves are all the ending scenes. Each scene has a value , and we use as the value of the -th scene. Once Katsuragi entering some new scene, he will get the value of that scene. However, even if Katsuragi enters some scenes for more than once, he will get for only once.

For his outstanding ability in playing gal games, Katsuragi is able to play the game times simultaneously. Now you are asked to calculate the maximum total value he will get by playing that game for times.

Input
The first line contains an integer (), denoting the number of test cases.

For each test case, the first line contains two numbers , denoting the total number of scenes and the maximum times for Katsuragi to play the game ”XX island”.

The second line contains non-negative numbers, separated by space. The -th number denotes the value of the -th scene. It is guaranteed that all the values are less than or equal to .

In the following lines, each line contains two integers , implying we can transform from the -th scene to the -th scene.

We assume the first scene(i.e., the scene with index one) to be the opening scene(i.e., the root of the tree).

Output
For each test case, output ”Case #t:” to represent the -th case, and then output the maximum total value Katsuragi will get.

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

Sample Output
Case #1: 10
Case #2: 11

给出一个带点权的树,遍历k次这个树,每次只能从根节点到一个叶子结点,经过一个点时加上这个点的权值,但只能加一次。求最多能获得多少值、
先反向建图,从每个叶子结点搜索到根节点,记录这个节点能获得的值,然后从大到小排序,一次从最大的节点再次遍历记录值并将经过的节点标记以防之后再次加入运算,再将这些值从小到大排序取前k个就行

#include <iostream>#include <cstring>#include <string>#include <vector>#include <queue>#include <cstdio>#include <set>#include <math.h>#include <algorithm>#include <queue>#include <iomanip>#include <map>#include <cctype>#include <ctime>#define INF 0x3f3f3f3f#define MAXN 200005#define Mod 1000000007using namespace std;int n,k;struct Node{    long long sum;    int id;};struct Edge{    int to,next;} edge[MAXN<<2];Node tree[MAXN];int head[MAXN],tot,vis[MAXN];long long a[MAXN],x[MAXN];void add(int u,int v){    edge[tot].to=v;    edge[tot].next=head[u];    head[u]=tot++;}long long dfs1(int v){    if(vis[v])        return tree[v].sum;    tree[v].sum=a[v];    vis[v]=1;    for(int i=head[v]; i!=-1; i=edge[i].next)    {        int u=edge[i].to;        tree[v].sum+=dfs1(u);    }    return tree[v].sum;}long long dfs2(int v){    if(vis[v])        return 0;    tree[v].sum=a[v];    vis[v]=1;    for(int i=head[v]; i!=-1; i=edge[i].next)    {        int u=edge[i].to;        tree[v].sum+=dfs2(u);    }    return tree[v].sum;}bool cmp1(Node a,Node b){    return a.sum>b.sum;}bool cmp2(long long a,long long b){    return a>b;}int du[MAXN];int main(){    int t,cnt=1;    scanf("%d",&t);    while(t--)    {        tot=0;        memset(head,-1,sizeof(head));        memset(du,0,sizeof(du));        scanf("%d%d",&n,&k);        for(int i=1; i<=n; ++i)        {            scanf("%I64d",&a[i]);            tree[i].id=i;        }        for(int i=1; i<n; ++i)        {            long long u,v;            scanf("%I64d%I64d",&u,&v);            add(v,u);            du[u]++;        }        memset(vis,0,sizeof(vis));        for(int i=1; i<=n; ++i)            if(!vis[i])                tree[i].sum=dfs1(i);        sort(tree+1,tree+1+n,cmp1);        memset(vis,0,sizeof(vis));        for(int i=1;i<=n;++i)            x[i]=dfs2(tree[i].id);        sort(x+1,x+1+n,cmp2);        long long ans=0;        for(int i=1;i<=k;++i)            ans+=x[i];        printf("Case #%d: %I64d\n",cnt++,ans);    }    return 0;}
0 0
原创粉丝点击