HDU 5242 Game(贪心)

http://acm.hdu.edu.cn/showproblem.php?pid=5242

题意:

给出一棵树,每个节点都有一个权值,每次可以获得从根结点(1)到叶子节点上的所有权值和,每个节点只能获得一次。求k次操作后可以获得的最大权值和。

思路:

反向建图,首先求出所有节点到根节点的权值和,然后降序排序,从可以获得最大权值和的叶子节点开始计算。已经遍历过的节点就直接返回0。计算完后再次重新排序,取前面的k个较大值。

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstdio>
 4 #include<cstring>
 5 using namespace std;
 6 const int maxn = 1e5+5;
 7 typedef long long ll;
 8 int tot, n, k;
 9 ll val[maxn],head[maxn];
10 bool vis[maxn];
11 
12 struct node
13 {
14     int v,next;
15 }e[maxn];
16 
17 struct Node
18 {
19     int id;
20     ll sum;
21     bool operator< (const Node& rhs)const
22     {
23         return sum>rhs.sum;
24     }
25 }t[maxn];
26 
27 void addEdge(int u, int v)
28 {
29     e[tot].v = v;
30     e[tot].next = head[u];
31     head[u] = tot++;
32 }
33 
34 ll dfs1(int u)
35 {
36     if(vis[u])  return t[u].sum;
37     vis[u] = true;
38     t[u].sum = val[u];
39     for(int i=head[u];i!=-1;i=e[i].next)
40     {
41         int v = e[i].v;
42         t[u].sum += dfs1(v);
43     }
44     return t[u].sum;
45 }
46 
47 ll dfs2(int u)
48 {
49     if(vis[u])  return 0;
50     vis[u] = true;
51     ll tmp = val[u];
52     for(int i=head[u];i!=-1;i=e[i].next)
53     {
54         int v = e[i].v;
55         tmp += dfs2(v);
56     }
57     return tmp;
58 }
59 
60 int main()
61 {
62     //freopen("in.txt","r",stdin);
63     int T;
64     int cas = 0;
65     scanf("%d",&T);
66     while(T--)
67     {
68         tot = 0;
69         memset(head,-1,sizeof(head));
70         scanf("%d%d",&n,&k);
71         for(int i=1;i<=n;i++)  scanf("%lld",&val[i]);
72         for(int i=1;i<n;i++)
73         {
74             int u,v;
75             scanf("%d%d",&u,&v);
76             addEdge(v,u);
77         }
78         memset(vis,0,sizeof(vis));
79         memset(t,0,sizeof(t));
80         for(int i=1;i<=n;i++)
81         {
82             t[i].id = i;
83             t[i].sum = dfs1(i);
84         }
85         sort(t+1,t+n+1);
86         memset(vis,0,sizeof(vis));
87         for(int i=1;i<=n;i++)
88         {
89             int root = t[i].id;
90             t[i].sum = dfs2(root);
91         }
92         sort(t+1,t+n+1);
93         ll ans = 0;
94         for(int i=1;i<=k;i++)
95             ans += t[i].sum;
96         printf("Case #%d: %lld\n",++cas,ans);
97     }
98     return 0;
99 }

猜你喜欢

转载自www.cnblogs.com/zyb993963526/p/9258562.html