VIJOS1476旅游规划[树形DP 树的直径]
描述
W市的交通规划出现了重大问题,市政府下决心在全市的各大交通路口安排交通疏导员来疏导密集的车流。但由于人员不足,W市市长决定只在最需要安排人员的路口安放人员。具体说来,W市的交通网络十分简单,它包括n个交叉路口和n-1条街道,任意一条街道连接两个交叉路口,并且任意两个交叉路口之间都存在一条路径互相连接。经过长期调查结果显示如果一个交叉路口位于W市交通网的最长路径上,那么这个路口必然拥挤不堪,所谓最长路径定义为某条路径p=(v1,v2,v3…vk),路径经过的路口各不相同且城市中不存在长度>k的路径(因此可能存在着不唯一的最长路径)。因此W市市长希望知道有哪些路口位于城市交通网的最长路径之上。
格式
输入格式
第一行包括一个整数n。
之后的n-1行每行包括两个整数u, v表示编号为u和v的路口之间存在着一条街道(注意:路口被依次编号为0到n-1)
输出格式
输出包括若干行,每行包括一个整数——某个位于最长路上路口的编号。
为了确保解唯一,我们规定位于所有最长路上的路口按编号顺序从小到大输出。
提示
这里存在着若干条最长路径,其中的两条是3-1-0-2-5与8-4-0-6-9,他们的长度都是5,但是不存在长度>5的路径且所有最长路径都不包括路口7,所以答案中没有7。
数据范围:
对于50%的数据保证n<=1000
对于100%的数据保证n<=200000
//90分 自己那个方法
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=;
int n,u,v;
struct edge{
int ne,v;
}e[N*];
int h[N],cnt=;
void ins(int u,int v){
cnt++;
e[cnt].v=v; e[cnt].ne=h[u]; h[u]=cnt;
cnt++;
e[cnt].v=u; e[cnt].ne=h[v]; h[v]=cnt;
}
int f[N][];
int dp(int u,int fa){ //cout<<u<<" u\n";
int &ans=f[u][],&ans2=f[u][];
if(ans!=-) return ans;
ans=;
for(int i=h[u];i;i=e[i].ne){
int v=e[i].v;
if(v==fa) continue; int d=dp(v,u)+;
if(ans<d) ans2=ans,ans=d;
else if(ans2<d) ans2=d;
}
//printf("ans %d %d %d\n",u,ans,ans2);
return ans;
}
int ans[N],num=,vis[N];
void dfs(int u){//cout<<u<<" dfs\n";
if(!vis[u]) ans[++num]=u;
vis[u]=;
for(int i=h[u];i;i=e[i].ne){
int v=e[i].v;
if(f[v][]==f[u][]-)
dfs(v);
}
}
int main(){
scanf("%d",&n);
for(int i=;i<=n-;i++) {
scanf("%d%d",&u,&v);
ins(u+,v+);
}
memset(f,-,sizeof(f));
dp(,-); int root,mx=-1e9;
for(int i=;i<=n;i++){
if(f[i][]+f[i][]+>mx){
mx=f[i][]+f[i][]+;
root=i;
}
}
ans[++num]=root; //printf("root %d %d %d\n",root,f[root][0],f[root][1]);
for(int i=h[root];i;i=e[i].ne){
int v=e[i].v;
if(f[v][]==f[root][]-||f[v][]==f[root][]-) dfs(v);
}
sort(ans+,ans++num);
for(int i=;i<=num;i++) printf("%d\n",ans[i]-);
}
//AC 正解
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=;
int n,u,v;
struct edge{
int ne,v;
}e[N*];
int h[N],cnt=;
void ins(int u,int v){
cnt++;
e[cnt].v=v; e[cnt].ne=h[u]; h[u]=cnt;
cnt++;
e[cnt].v=u; e[cnt].ne=h[v]; h[v]=cnt;
}
int f[N][];
int dp(int u,int fa){ //cout<<u<<" u\n";
int &ans=f[u][],&ans2=f[u][];
if(ans!=-) return ans;
ans=;
for(int i=h[u];i;i=e[i].ne){
int v=e[i].v;
if(v==fa) continue; int d=dp(v,u)+;
if(ans<d) ans2=ans,ans=d;
else if(ans2<d) ans2=d;
}
//printf("ans %d %d %d\n",u,ans,ans2);
return ans;
} int g[N];
void dp2(int u,int fa){
int cnt=;
for(int i=h[u];i;i=e[i].ne){
int v=e[i].v;
if(v==fa) continue;
if(f[v][]==f[u][]-) cnt++;
}
for(int i=h[u];i;i=e[i].ne){
int v=e[i].v;
if(v==fa) continue;
if(f[v][]!=f[u][]- || (f[v][]==f[u][]- && cnt>)) g[v]=max(g[u],f[u][])+;
else g[v]=max(g[u],f[u][])+;
dp2(v,u);
}
}
int ans[N],num=;
int main(){
scanf("%d",&n);
for(int i=;i<=n-;i++) {
scanf("%d%d",&u,&v);
ins(u+,v+);
}
memset(f,-,sizeof(f));
dp(,-);
dp2(,-); int mx=-1e9;
for(int i=;i<=n;i++){
if(f[i][]+f[i][]+>mx){
mx=f[i][]+f[i][]+;
}
}
for(int i=;i<=n;i++){
if(f[i][]+max(g[i],f[i][])+==mx) ans[++num]=i;
}
sort(ans+,ans++num);
for(int i=;i<=num;i++) printf("%d\n",ans[i]-); }
VIJOS1476旅游规划[树形DP 树的直径]的更多相关文章
- HDU 2196.Computer 树形dp 树的直径
Computer Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Su ...
- hdu 4607 树形dp 树的直径
题目大意:给你n个点,n-1条边,将图连成一棵生成树,问你从任意点为起点,走k(k<=n)个点,至少需要走多少距离(每条边的距离是1): 思路:树形dp求树的直径r: a:若k<=r+1 ...
- computer(树形dp || 树的直径)
Computer Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Su ...
- POJ 3162.Walking Race 树形dp 树的直径
Walking Race Time Limit: 10000MS Memory Limit: 131072K Total Submissions: 4123 Accepted: 1029 Ca ...
- Computer(HDU2196+树形dp+树的直径)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2196 题目: 题意:有n台电脑,每台电脑连接其他电脑,第i行(包括第一行的n)连接u,长度为w,问你每 ...
- poj3162 树形dp|树的直径 + 双单调队列|线段树,好题啊
题解链接:https://blog.csdn.net/shiqi_614/article/details/8105149 用树形dp是超时的,, /* 先求出每个点可以跑的最长距离dp[i][0|1] ...
- hdu-2169 Computer(树形dp+树的直径)
题目链接: Computer Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- 树形DP+树状数组 HDU 5877 Weak Pair
//树形DP+树状数组 HDU 5877 Weak Pair // 思路:用树状数组每次加k/a[i],每个节点ans+=Sum(a[i]) 表示每次加大于等于a[i]的值 // 这道题要离散化 #i ...
- [HDU 5293]Tree chain problem(树形dp+树链剖分)
[HDU 5293]Tree chain problem(树形dp+树链剖分) 题面 在一棵树中,给出若干条链和链的权值,求选取不相交的链使得权值和最大. 分析 考虑树形dp,dp[x]表示以x为子树 ...
随机推荐
- Javascript - Arraylike的7种实现
jQuery的崛起让ArrayLike(类数组)在javascript中大放异彩,它的出现为一组数据的行为(函数)扩展提供了基础. 类数组和数组相似,具有数组的某些行为,但是它相比数组可以更加自由的扩 ...
- 在ArcGIS中如何进行POI点抽稀
对POI点添加权重等级类型信息.例如添加短整形字段Weight,并根据业务逻辑设置不同种类的POI的权重值,如分5类,0代表重要性最低的POI,4代表重要性最高. 在ArcMap的标注管理栏中,设置使 ...
- iOS上架90034问题解决
开发完成的APP,我们当然要上传到AppStore里面了,这可是我们心血的结晶. 可是,就当我们兴奋之余,却发现我们的App根本无法上传到AppStore.我们百度.谷歌了N种方法,就像我这种逗逼,整 ...
- WIFI热点
1.wifi热点是指把手机的接收GPRS.3G或4G信号转化为wifi信号再发出去,这样手机就成了一个WIFI热点. 2.手机必须有无线AP功能,才能当做热点.有些系统自带建热点这个功能比如IOS(比 ...
- 【代码笔记】iOS-改变导航条标题的颜色为红色
一,效果图. 二,代码. RootViewController.m - (void)viewDidLoad { [super viewDidLoad]; // Do any additional se ...
- OC中的Block的那些事
Block封装了一段代码,可以在任何时候执行 Block可以作为函数参数或者函数的返回值,而其本身又可以带输入参数或返回值. 苹果官方建议尽量多用block.在多线程.异步任务.集合遍历.集合排序.动 ...
- 小试ildasm,ilasm,ilspy
选择了微耕的软件(为什么选择它,因为微耕的二次开发实在太牛了,只给文档,一切技术问题都不回答.文档也是只公开基本的东西) 第一个功能:换文字 第二个功能:插入一个新的程序集,在做某些事情前先做我想做的 ...
- Mac OS 下的解压缩软件——The Unarchiver
The Unarchiver 是 Mac 上最流行的解压软件,免费开源.操作方式与系统自带解压工具 Archive Utility.app 一样,双击自动解压.最爽的一点是把解压后原始文件直接仍进废纸 ...
- javascript中,对于this指向的浅见
# this的指向在函数创建的时候确定不了.只有在执行的时候,才可以确定. ## 1 . 这里的this指向window window.fn(); 所以this.user是undefined func ...
- 网络编程2--毕向东java基础教程视频学习笔记
Day 23 08 Udp接收端09 Udp键盘录入数据方式10 Udp聊天11 TCP传输12 TCP传输213 TCP练习14 TCP复制文件 08 Udp接收端 需求:定义一个应用程序,用于接收 ...