1463. Happiness to People!
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!相关推荐
- ural(Timus) 1463. Happiness to People!
树DP 题意:输入n和m,表示n个城市,m条无向边,下面一行n个数字,表示每个城市的权值,下面m行是每条边的信息,u,v,w,顶点和边权.问你从一个城市出发,走出一条路线,使得权值和最大,权值和包括这 ...
- 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. ...
- 基于bert模型的文本分类研究:“Predict the Happiness”挑战
1. 前言 在2018年10月,Google发布了新的语言表示模型BERT-"Bidirectional Encoder Representations from Transformers& ...
- BZOJ 2127: happiness
2127: happiness Time Limit: 51 Sec Memory Limit: 259 MB Submit: 2084 Solved: 1028 Description 高一一班 ...
- happiness[国家集训队2011(吴确)]
[试题来源] 2011中国国家集训队命题答辩 [问题描述] 高一一班的座位表是个n*m的矩阵,经过一个学期的相处,每个同学和前后左右相邻的同学互相成为了好朋友.这学期要分文理科了,每个同学对于选择文科 ...
- 夯实基础项目工程之图论——Uncle Bogdan and Country Happiness,Graph Coloring,How Many Paths?,Array Differentiation
文章目录 做题情况项目报告 Uncle Bogdan and Country Happiness Graph Coloring How Many Paths? Array Differentiatio ...
- 1388C. Uncle Bogdan and Country Happiness
C. Uncle Bogdan and Country Happiness 纯纯DFS #include <bits/stdc++.h> using namespace std; cons ...
- Bzoj 2127 happiness 最小割
happiness 题解: 将图转换成最小割. 将割完的图中与S相连的点看做选文科, 与T相连的点看做选理科. flow(s, u) = 文科值 flow(u,t) = 理科值 假设u 和 v 一起选 ...
- 国家集训队2011 happiness
[试题来源] 2011中国国家集训队命题答辩 [问题描述] 高一一班的座位表是个n*m的矩阵,经过一个学期的相处,每个同学和前后左右相邻的同学互相成为了好朋友.这学期要分文理科了,每个同学对于选择文科 ...
最新文章
- 计算圆弧与矩形相交_GIS算法:3_拓扑空间关系计算模型DE-9IM
- hadoop 开启防火墙_Hadoop部署一Hadoop安装
- SaaS业务的价值评估
- java适配器模式 场景_Java设计模式之《适配器模式》及应用场景
- 【渝粤教育】国家开放大学2018年秋季 1313T学前儿童卫生与保健 参考试题
- PCB设计的基本步骤
- Dubbo学习总结(9)——Apache Dubbo Roadmap 2019
- 员工请假审批系统 php,php073企业考勤请假系统
- python调用函数出现未定义_python中函数调用中的“未定义”参数
- 即时与及时有什么区别_即时与及时有什么区别?
- 华北电力大学控制与计算机工程学院怎么样,华北电力大学控制与计算机工程学院实践部10月25日动保劳动感想...
- 计算机作业攒机单,计算机攒机作业.docx
- WebView获取当前网页的页面元素
- BootStrap栅格之间留出空隙
- ES部署报错 max file size 和 kibana 报错File size limit exceeded
- linux设置网口ip地址,linux网口设置ip地址
- 使用余弦定理计算反三角函数却报超出定义域
- douboo php_【H5游戏源码】Long/Hu/Dou/微信游戏源码+全套开源完整源码[整站打包]
- 如何进行自我职业规划?
- 直流电机ULN2003(按键控制转动)
热门文章
- 一劳永逸:域名支持通配符,ASP.NET Core中配置CORS
- 手把手教你如何写简历
- 常见Java面试题之如何实现对象克隆
- 查看MongoDB索引的使用,管理索引
- Oracle 11g创建Interval分区表
- Oracle之AUTHID CURRENT_USER
- Oracle中Cluster Table的使用
- 域渗透基础之环境搭建(单域到组件域林)
- openwrt多wan限上下行速脚本,基于qosv4,imq模块替换成ifb模块[ZT]
- [转载][总结]函数getopt(),getopt_long及其参数optind