http://acm.timus.ru/problem.aspx?space=1&num=1463

树形DP

此题有个陷阱   就是图的本身是一个森林 不是树

由于所有 happiness 的值都为非负 所有最优路径一定是从一个叶子节点到另一个叶子节点(当然 两个节点可能一样)

思路:

包含一个节点 和 两个节点的 树特殊处理

对应3个节点以及3个节点以上的树 一定能找到一个初度 大于等于2 的点 以此点为根节点更新

对于这个树  dfs  记录每个点向下的第一最优路径选择 和第二最优路径选择

然后不断向上更新

最后 把所有向下路径至少两条的节点 将此类节点的两个最优路径 连起来的路径进行和最终答案比较 择优而选

刚开始用 vector 建图 结果超内存了 看来 vector 的时间和空间占用都比较大

代码及其注释:

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
#include<string>
#include <iomanip>
using namespace std;
const int N=50005;
int head[N],I;
struct node
{int j,h,next;
}side[N*2];//双向边
int out[N],sub[N],next1[N],next2[N];//初度 ,子树最优长度 ,第一选择路径,第二选择路径
vector<int>ans;
int a[N];
void Add(int i,int j,int h)
{side[I].j=j;side[I].h=h;side[I].next=head[i];head[i]=I++;
}
int Optimal(int i)//以此点为根节点的树中 最优路径长度
{if(out[i]==0)return a[i];if(out[i]==1)return a[i]+a[side[head[i]].j]+side[head[i]].h;return a[i]+side[next1[i]].h+sub[side[next1[i]].j]+side[next2[i]].h+sub[side[next2[i]].j];
}
int Fhappy(int x,int i)//从x节点选择i路径向下的路径长度
{return (side[i].h+sub[side[i].j]);
}
int dfs(int x,int pre)
{for(int t=head[x];t!=-1;t=side[t].next){int l=side[t].j;if(l==pre)continue;dfs(l,x);if(next2[x]==-1||Fhappy(x,t)>Fhappy(x,next2[x]))//更新最优选择路径next2[x]=t;elsecontinue;if(next1[x]==-1||Fhappy(x,next2[x])>Fhappy(x,next1[x]))//更新最优选择路径swap(next2[x],next1[x]);}sub[x]=a[x];if(next1[x]!=-1)sub[x]+=Fhappy(x,next1[x]);return sub[x];
}
int main()
{//freopen("data.txt","r",stdin);int n,m;while(scanf("%d %d",&n,&m)!=EOF){memset(head,-1,sizeof(head));I=0;memset(next1,-1,sizeof(next1));memset(next2,-1,sizeof(next2));memset(out,0,sizeof(out));for(int i=1;i<=n;++i)scanf("%d",&a[i]);int l,r,h;while(m--){scanf("%d %d %d",&l,&r,&h);Add(l,r,h);Add(r,l,h);++out[l];++out[r];}int k=-1;for(int i=1;i<=n;++i){if(out[i]>=2&&next1[i]==-1){dfs(i,-1);if(k==-1||Optimal(i)>Optimal(k))k=i;}}for(int i=1;i<=n;++i){if(out[i]>=3){if(k==-1||Optimal(i)>Optimal(k))k=i;}else if(out[i]==0)//只有一个点才情况{if(k==-1||Optimal(i)>Optimal(k))k=i;}else if(out[i]==1&&out[side[head[i]].j]==1)//只有两个点的情况{if(k==-1||Optimal(i)>Optimal(k))k=i;}}if(out[k]<=1){printf("%d\n",Optimal(k));if(out[k]==0){printf("1\n");printf("%d\n",k);}else{printf("2\n");printf("%d %d\n",k,side[head[k]].j);}continue;}ans.clear();ans.push_back(k);//将最优路径存到 ans 里面int tmp=side[next1[k]].j;do{ans.push_back(tmp);if(next1[tmp]==-1)break;tmp=side[next1[tmp]].j;}while(true);tmp=side[next2[k]].j;do{ans.insert(ans.begin(),tmp);if(next1[tmp]==-1)break;tmp=side[next1[tmp]].j;}while(true);printf("%d\n",Optimal(k));printf("%d\n",ans.size());for(unsigned int i=0;i<ans.size();++i)printf("%d ",ans[i]);printf("\n");}return 0;
}

转载于:https://www.cnblogs.com/liulangye/archive/2012/10/29/2744299.html

1463. Happiness to People!相关推荐

  1. ural(Timus) 1463. Happiness to People!

    树DP 题意:输入n和m,表示n个城市,m条无向边,下面一行n个数字,表示每个城市的权值,下面m行是每条边的信息,u,v,w,顶点和边权.问你从一个城市出发,走出一条路线,使得权值和最大,权值和包括这 ...

  2. The greatest happiness 2019-11-13

    One of the greatest happiness of a person is to devote himself to a career that he is interested in. ...

  3. 基于bert模型的文本分类研究:“Predict the Happiness”挑战

    1. 前言 在2018年10月,Google发布了新的语言表示模型BERT-"Bidirectional Encoder Representations from Transformers& ...

  4. BZOJ 2127: happiness

    2127: happiness Time Limit: 51 Sec  Memory Limit: 259 MB Submit: 2084  Solved: 1028 Description 高一一班 ...

  5. happiness[国家集训队2011(吴确)]

    [试题来源] 2011中国国家集训队命题答辩 [问题描述] 高一一班的座位表是个n*m的矩阵,经过一个学期的相处,每个同学和前后左右相邻的同学互相成为了好朋友.这学期要分文理科了,每个同学对于选择文科 ...

  6. 夯实基础项目工程之图论——Uncle Bogdan and Country Happiness,Graph Coloring,How Many Paths?,Array Differentiation

    文章目录 做题情况项目报告 Uncle Bogdan and Country Happiness Graph Coloring How Many Paths? Array Differentiatio ...

  7. 1388C. Uncle Bogdan and Country Happiness

    C. Uncle Bogdan and Country Happiness 纯纯DFS #include <bits/stdc++.h> using namespace std; cons ...

  8. Bzoj 2127 happiness 最小割

    happiness 题解: 将图转换成最小割. 将割完的图中与S相连的点看做选文科, 与T相连的点看做选理科. flow(s, u) = 文科值 flow(u,t) = 理科值 假设u 和 v 一起选 ...

  9. 国家集训队2011 happiness

    [试题来源] 2011中国国家集训队命题答辩 [问题描述] 高一一班的座位表是个n*m的矩阵,经过一个学期的相处,每个同学和前后左右相邻的同学互相成为了好朋友.这学期要分文理科了,每个同学对于选择文科 ...

最新文章

  1. 计算圆弧与矩形相交_GIS算法:3_拓扑空间关系计算模型DE-9IM
  2. hadoop 开启防火墙_Hadoop部署一Hadoop安装
  3. SaaS业务的价值评估
  4. java适配器模式 场景_Java设计模式之《适配器模式》及应用场景
  5. 【渝粤教育】国家开放大学2018年秋季 1313T学前儿童卫生与保健 参考试题
  6. PCB设计的基本步骤
  7. Dubbo学习总结(9)——Apache Dubbo Roadmap 2019
  8. 员工请假审批系统 php,php073企业考勤请假系统
  9. python调用函数出现未定义_python中函数调用中的“未定义”参数
  10. 即时与及时有什么区别_即时与及时有什么区别?
  11. 华北电力大学控制与计算机工程学院怎么样,华北电力大学控制与计算机工程学院实践部10月25日动保劳动感想...
  12. 计算机作业攒机单,计算机攒机作业.docx
  13. WebView获取当前网页的页面元素
  14. BootStrap栅格之间留出空隙
  15. ES部署报错 max file size 和 kibana 报错File size limit exceeded
  16. linux设置网口ip地址,linux网口设置ip地址
  17. 使用余弦定理计算反三角函数却报超出定义域
  18. douboo php_【H5游戏源码】Long/Hu/Dou/微信游戏源码+全套开源完整源码[整站打包]
  19. 如何进行自我职业规划?
  20. 直流电机ULN2003(按键控制转动)

热门文章

  1. 一劳永逸:域名支持通配符,ASP.NET Core中配置CORS
  2. 手把手教你如何写简历
  3. 常见Java面试题之如何实现对象克隆
  4. 查看MongoDB索引的使用,管理索引
  5. Oracle 11g创建Interval分区表
  6. Oracle之AUTHID CURRENT_USER
  7. Oracle中Cluster Table的使用
  8. 域渗透基础之环境搭建(单域到组件域林)
  9. openwrt多wan限上下行速脚本,基于qosv4,imq模块替换成ifb模块[ZT]
  10. [转载][总结]函数getopt(),getopt_long及其参数optind