标签:scan minus php ++ print numbers ring ogr ons
Time Limit: 3000/1500 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1385 Accepted Submission(s): 452
/* * @Author: lyuc * @Date: 2017-04-29 19:33:34 * @Last Modified by: lyuc * @Last Modified time: 2017-04-29 21:16:49 */ /* 题意:一棵树有n个节点,每个节点有一个价值。一个人从根节点走到某叶子节点算一次游戏,可以 * 获得经过节点的所有价值。但每个节点的价值只能被获得一次。问在同一棵树上进行K次游戏 * ,最多能获得多少价值。 * * 思路:首先从叶节点开始记录每个叶子节点到达根节点的权值和,按照权值排序,然后按照这个顺序 * 再按照权值排序,然后在统计叶子节点到达根节点的权值和,不过这次每个节点的值只能取一 * 次,然后再按照权值和排序,在取前k个叶子节点的值 */ #include <iostream> #include <stdio.h> #include <string.h> #include <vector> #include <algorithm> #define LL long long #define MAXN 100005 using namespace std; struct Node{ int id; LL val; bool operator <(const Node& other) const{ return val>other.val; } }node[MAXN]; int t; int n,k; int u,v; LL res; LL val[MAXN]; int pos[MAXN];//记录那个定点是哪个 vector<int>edge[MAXN];//从根节点开始建树 LL dfs1(int u){//第一遍dfs,统计每个节点到根节点的值 if(node[u].val) return node[u].val; LL res=val[u]; for(int i=0;i<edge[u].size();i++){ int v=edge[u][i]; res+=dfs1(v); } node[u].val+=res; } LL dfs2(int u){//第二遍dfs,统计每个节点到根节点的值,每个节点的值只取一次 if(node[pos[u]].val) return 0; node[pos[u]].val=val[u]; for(int i=0;i<edge[u].size();i++){ int v=edge[u][i]; node[pos[u]].val+=dfs2(v); } return node[pos[u]].val; } void init(){ for(int i=0;i<MAXN;i++){ edge[i].clear(); node[i].val=0; } res=0; } int main(){ // freopen("in.txt","r",stdin); scanf("%d",&t); for(int ca=1;ca<=t;ca++){ init(); printf("Case #%d: ",ca); scanf("%d%d",&n,&k); for(int i=1;i<=n;i++)//节点的值 scanf("%lld",&val[i]); for(int i=1;i<n;i++){//建边 scanf("%d%d",&u,&v); edge[v].push_back(u); } for(int i=1;i<=n;i++){ node[i].id=i;//节点初始化 pos[i]=i; if(node[i].val==0) dfs1(node[i].id); } sort(node+1,node+n+1);//给节点排序用于贪心 for(int i=1;i<=n;i++){//将节点的值清零 node[i].val=0; pos[node[i].id]=i; } for(int i=1;i<=n;i++){ if(node[i].val==0){ dfs2(node[i].id); } } sort(node+1,node+n+1); for(int i=1;i<=n;i++){ node[i].val=0; pos[node[i].id]=i; } for(int i=1;i<=n&&k;i++){ if(node[i].val==0){ dfs2(node[i].id); k--; res+=node[i].val; } } printf("%lld\n",res); } return 0; }
标签:scan minus php ++ print numbers ring ogr ons
原文地址:http://www.cnblogs.com/wuwangchuxin0924/p/6786322.html