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为子树 ...
随机推荐
- there is no spatial analyst license available or enabled
解决方案:右击license—属性
- 更改SAP的字段翻译
TC:SE63在SAP用户选择屏幕中,用鼠标选定一个栏位后按F1键,可以看到SAP对其具体解释,通常这种解释文本分为两部分,一部分为标题,一部分为正文.比如: 有时,SAP的翻译让人感觉很别扭,对于 ...
- Shapely中的几何图形操作
Geometric Objects object.area Returns the area (float) of the object. object.bounds Returns a (minx, ...
- 关于一些网络代理实现智能流量分流的研究(PAC脚本介绍及利用)
因为工作原因,需要访问一些国外的网站(科学上网),但直接FQ并不方便,于是研究了一些代理软件,比如Nydus,Green等, 在Nydus的Proxy版本中发现了实现国内国外流量的智能分流的办法,通过 ...
- Linux学习心得之 LVM管理与Linux系统安装
作者:枫雪庭 出处:http://www.cnblogs.com/FengXueTing-px/ 欢迎转载 LVM管理与Linux系统安装 1.前言 2.LVM 简介与术语 3.LVM 使用 4.Li ...
- Objective-C 快速入门--基础(二)
1.什么是继承?OC中的继承有哪些特点? “继承”是面向对象软件技术当中的一个概念.如果一个类A继承自另一个类B,就把这个A称为"B的子类",而把B称为"A的父类&quo ...
- Several ports (8005, 8080, 8009) required by Tomcat v7.0 Server at localhost are already in use.解决办法
Several ports (8005, 8080, 8009) required by Tomcat v7.0 Server at localhost are already in use. The ...
- Android 短信的还原
上篇文章讲到<Android 短信的备份>,本文主要实现Android 短信的还原,即是将一条 布局文件: <RelativeLayout xmlns:android="h ...
- 优化MySchool数据库(四)
关于“无法附件数据库”过程的遇到的问题: 1.数据文件本身,具有访问权限的限制 ---- 选中 数据库文件所在的文件夹---->右键菜单(属性)----> 安全 --->User用户 ...
- TextView 字数限制
给大家推荐一个 无bug的 字数限制 http://blog.csdn.net/u012460084/article/details/50377928