树DP

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

题中有一句话出卖了它是个树DP:It turned out that if Petrovich can fly (using one or several flights) from town i to town j, then there is exactly one way to do this.

从一个顶点去另一个顶点如果连通的话只有一条路径,说明这个无向图其实是个无根树,所以又变成了经典问题,在无根树中找两点使它们的路径最长,不过这里要加上点的权值而已,是一样的,另外一个点是要记录路径的,输出路径中经过了多少个点,并且沿路径输出每一个点,如果有多条路径任意一条即可

DP思路不说了,可以找前面的题解里面有详细的讲解,说说输出路径。我是分两部分来输出路径的,根到叶子的最大值为一个部分,到叶子的次大值是另一个部分,根据路径输出的要求,前面部分要递归输出,或者可以用一个栈保存,比较懒就用了stl的stack来保存路径,后面的部分不用递归,直接迭代下去,但是为了统计点的个数所以先保存,用了stl的queue来保存路径

整个题目其实不难,注意细节即可

#include <cstdio>
#include <cstring>
#include <utility>
#include <vector>
#include <stack>
#include <queue>
#include <algorithm>
using namespace std;
#define N 50010typedef long long ll;
typedef pair<ll,ll> pll;
bool vis[N];
vector<pll>a[N];
stack<int>s;
queue<int>q;
ll val[N];
ll dp[N][2];
ll ans;
int n,m,root;
int p[N][2];void input()
{for(int i=0; i<=n; i++) a[i].clear();for(int i=1; i<=n; i++) scanf("%lld",&val[i]);for(int i=0; i<m; i++){int u,v,w;pll tmp;scanf("%d%d%d",&u,&v,&w);tmp.first=v; tmp.second=w; a[u].push_back(tmp);tmp.first=u; tmp.second=w; a[v].push_back(tmp);}
}void dfs(int rt)
{vis[rt]=true;dp[rt][1]=dp[rt][0]=0; p[rt][1]=p[rt][0]=-1;int size=a[rt].size();for(int i=0; i<size; i++){pll tmp = a[rt][i];int v = tmp.first;int w = tmp.second;if(!vis[v]){dfs(v);if(dp[v][1] + w >= dp[rt][1]){dp[rt][0] = dp[rt][1];p[rt][0] = p[rt][1];dp[rt][1] = dp[v][1]+w;p[rt][1] = v;}else if(dp[v][1] + w > dp[rt][0]){dp[rt][0] = dp[v][1] + w;p[rt][0] = v;}}}dp[rt][1] += val[rt];dp[rt][0] += val[rt];if( dp[rt][1]+dp[rt][0]-val[rt] > ans){root=rt;ans = dp[rt][1]+dp[rt][0]-val[rt];}
}int Path1(int rt)
{int cc=1;int u;while(!s.empty()) s.pop();s.push(rt);for(u=p[rt][1]; u!=-1; u=p[u][1]){s.push(u);cc++;}return cc;
}int Path2(int rt)
{int cc=0;int u;while(!q.empty()) q.pop();for(u=p[rt][0]; u!=-1; u=p[u][1]){q.push(u);cc++;}return cc;
}void solve()
{memset(vis,false,sizeof(vis));memset(p,-1,sizeof(p));ans=-1;   /*初始化为ans=0;root=1; //不要初始化为0*/for(int i=1; i<=n; i++)if(!vis[i])dfs(i);printf("%lld\n",ans);int c1=Path1(root);int c2=Path2(root);printf("%d\n",c1+c2);while(!s.empty()){int t=s.top();s.pop();if(t!=root) printf("%d ",t);else        printf("%d",t);}while(!q.empty()){int t=q.front();q.pop();printf(" %d",t);}printf("\n");
}int main()
{while(scanf("%d%d",&n,&m)!=EOF){input();solve();}return 0;
}

转载于:https://www.cnblogs.com/scau20110726/archive/2013/04/11/3013443.html

ural(Timus) 1463. Happiness to People!相关推荐

  1. 1463. Happiness to People!

    http://acm.timus.ru/problem.aspx?space=1&num=1463 树形DP 此题有个陷阱   就是图的本身是一个森林 不是树 由于所有 happiness 的 ...

  2. Ural(Timus) 1146. Maximum Sum

    DP,最大子矩阵和:先按列压缩为一维i,在用最大连续子序列和来求.在枚举列压缩求和的时候,为了提高速度,可以在输入的时候先保存下来,就不用每次都去计算,不过再代码中没有写 另外这题不允许空矩阵,即至少 ...

  3. Ural(Timus) 1081. Binary Lexicographic Sequence

    DP(解码) 题意:给出一个串的长度n,串只有0,1组成,但是不能有两个相邻的1.按字典序给串排列,最先肯定是0000,接着是0001,依此类推.给一个数字m,输出在长度为n的情况下,第m个排列的串是 ...

  4. ural(Timus) 1019 Line Painting

    线段树 题意:很明显的线段树.做了这题更加让我注意了用点和用段来建树的区别.这题是用点来表示线段的.一开始从0到10^9这个点之间的线段都是白色的,然后m个更新,每个更新 a,b,col,表示从点a到 ...

  5. 有哪些好的刷题网站?2018年最受欢迎的编程挑战网站

    本文转自 https://blog.csdn.net/UzV80PX5V412NE/article/details/78653695 2018年最受欢迎的编程挑战网站 1.TopCoder 2.Cod ...

  6. Online Judge汇总

    1.SGU(Saratov State University Online Contester)     有很多难题,还有Virtual Contest,推荐推荐.     地址: http://ac ...

  7. 非常好用的在线编程网站

    编程几乎已经成为了人类所知每个行业的必要组成部分,如今有越来越多的人开始了他们的编程之旅. 如果你正在在学习编程,那么我可以告诉你一个提高技能的好方法,那就是敢于去解决编码过程中遇到的难题.解决不同类 ...

  8. timus 1192. Ball in a Dream URAL 解题报告 平生第一个计算几何+高中物理

    timus   1192. Ball in a Dream    URAL  解题报告   平生第一个计算几何+高中物理 看来高中物理没白学,这个题用我仅剩下的高中物理学知识分析下竟然找到了方法,再加 ...

  9. timus 1513. Lemon Tale URAL 解题报告

    timus   1513. Lemon Tale    URAL 解题报告 题目大意:就是一行字符,LB组成,一个检测员呢和L有仇啊,只要是多余K个连续的L出现,那么这条语句就不合法,为此,三名程序猿 ...

最新文章

  1. 【翻译】SQL Server索引进阶:第八级,唯一索引
  2. 用flex进行网易云音乐界面构建和布局解析(2)
  3. mysql表名忽略大小写
  4. 迭代开发个人总结20160702
  5. 剥开比原看代码03:比原是如何监听p2p端口的
  6. 新浪微博api接口java_新浪微博API(java版)
  7. Python微信公众号接入图灵机器人
  8. 论“詹姆斯*哈登”到底是不是球队毒瘤
  9. android 清理工具,安卓清理君深度清理软件/真心强
  10. 开发愤怒的小鸟的Lua语言:Wax框架详解
  11. Java旅游管理系统的设计与实现毕业设计
  12. 按步搭建简单IoT微服务(2)
  13. MDM三权分立及分类分级权限说明
  14. 计算机体系架构(1)计算机组成原理
  15. PHP连接MSSQL配置和PHP代码演示
  16. 谈谈mysql update语句 set顺序问题、列交换sql实现及多表更新注意事项
  17. 数据结构c语言版题库编程,数据结构习题库(c语言版)
  18. 放大器的传递函数_所谓传递函数
  19. 堆、栈、队列的区别以及使用场景
  20. VSCode + JSDoc 完美实现(almost)JavaScript代码提示

热门文章

  1. 软RAID创建手册-win2003
  2. C#中处理XML文档的方法
  3. python3实现下载ftp上的文件
  4. 计算机查找文件的速度,如何快速搜索文件_怎么加快电脑里的文件搜索速度
  5. Xamarin XAML语言教程模板视图TemplatedView(一)
  6. Hierarchy视图里的Transform和Camera组件
  7. Android渗透测试Android渗透测试入门教程大学霸
  8. 计算机反面的考研专业,2018计算机考研:历年准考证打印常见七大问题
  9. 无线AP、WiFi、WLAN是什么关系?
  10. php一个英文几个字符,PHP指定截取字符串中的中英文或数字字符的实例分享