BZOJ1509: [NOI2003]逃学的小孩
2016-01-14 13:32
435 查看
题目
bzoj1509Input
第一行是两个整数N(3<=N<= 200000)和M,分别表示居住点总数和街道总数。以下M行,每行给出一条街道的信息。第i+1行包含整数Ui、Vi、Ti(1<=Ui, Vi<= N,1<= Ti<= 1000000000),表示街道i连接居住点Ui和Vi,并且经过街道i需花费Ti分钟。街道信息不会重复给出。
Output
仅包含整数T,即最坏情况下Chris的父母需要花费T分钟才能找到Chris。
Sample Input
4 31 2 12 3 13 4 1
Sample Output
4
题解
我们考虑最坏情况,一定是有折返的。由这么两种情况:对于第一种情况,我们只要找从一个点出发的最长的三条不重叠路径即可。
设这三条路径长度为a,b,c(a≤b≤c),那么答案就是a+2∗b+c。
如何统一这两种情况?我们只要允许长度为0的路径就行了。
接下来进行树DP就行了。
两次dfs,一次求出子树中前1,2,3的路径。第二次再考虑父亲。同时还有注意记录路径是由哪个点得到的。
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> using namespace std; #define N 200010 typedef long long ll; struct edge{ int x,next,d; }e[N*2]; ll dis [3],ans; int first ,n,m,pre [3],x,y,z,tot; inline void add(int x,int y,int z){ e[++tot].d=z; e[tot].x=y; e[tot].next=first[x]; first[x]=tot; } inline bool updata(int x,int y,ll d){ if(d>dis[x][0]){ dis[x][2]=dis[x][1]; pre[x][2]=pre[x][1]; dis[x][1]=dis[x][0]; pre[x][1]=pre[x][0]; dis[x][0]=d; pre[x][0]=y; return true; }else if(d>dis[x][1]){ dis[x][2]=dis[x][1]; pre[x][2]=pre[x][1]; dis[x][1]=d; pre[x][1]=y; return true; }else if(d>dis[x][2]){ dis[x][2]=d,pre[x][2]=y; return true; } return false; } void dfs(int x, int y){ for(int i=first[x];i;i=e[i].next) if(e[i].x!=y){ dfs(e[i].x,x); updata(x,e[i].x,(ll)e[i].d+dis[e[i].x][0]); } } void dp(int x,int y,int d){ for(int i=0;i<3;i++) if(pre[y][i]!=x) if(updata(x,y,(ll)d+dis[y][i]))break; for(int i=first[x];i;i=e[i].next) if(e[i].x!=y)dp(e[i].x,x,e[i].d); } char BUF[2000010],*buf,*end; #define getch() (buf==end?fread(BUF,1,2000000,stdin),buf=BUF,end=buf+2000000,*(buf++):*(buf++)) inline void read(int &x){ static char c; for(c=getch();c<'0'||c>'9';c=getch()); for(x=0;'0'<=c&&c<='9';c=getch())x=x*10+c-'0'; } int main(){ read(n); read(m); for(int i=1;i<=m;i++){ read(x); read(y); read(z); add(x,y,z); add(y,x,z); } dfs(1,0); dp(1,0,0); for(int i=1;i<=n;i++) //printf("%lld %lld %lld\n",dis[i][0],dis[i][1],dis[i][2]); if(dis[i][0]+2*dis[i][1]+dis[i][2]>ans) ans=dis[i][0]+2*dis[i][1]+dis[i][2]; printf("%lld\n",ans); return 0; }
相关文章推荐
- 批处理文件(.bat 文件)中%0、%1等是表示什么
- SVN—怎样安装SVNclient软件
- iOS ERROR: unable to get the receiver data from the DB 解决方式
- 微信公众平台开发学习系列(四):微信分享内容修改与分享之后才能访问某页面
- List泛型集合常用方法
- ES6--Iterator和for...of循环
- VS2010使用GDI+在picture control控件里面显示图片
- 【填坑中】学生信息管理系统
- [学习记录][css]基本视觉格式化
- Android Manifest.xml详解
- 安卓中RelativeLayout布局
- java批量读取
- Android自定义view解决TabWidget 的下方的横线(Strip)颜色问题
- 关于打印日志几个方法的列举
- no suitable driver mysql情况出现
- Java注释Override、Deprecated、SuppressWarnings详解
- self、 superclass 、 super的区别
- 【点滴积累,厚积薄发】windows schedule task中.exe程序的路径问题等问题总结
- tar linux 命令说明
- C语言-关于输入缓冲区