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为子树 ...
随机推荐
- [js开源组件开发]html5标签audio的样式更改
html5标签audio的样式更改 由于html5的流行,现在移动端大多数的需求都可以使用audio来播放音频,但您可能只是需要很简单的播放/停止效果,但不同的浏览器上的audio样式却不尽人意,所以 ...
- 编写高质量的Objective-C代码
点标记语法 属性和幂等方法(多次调用和一次调用返回的结果相同)使用点标记语法访问,其他的情况使用方括号标记语法. 良好的风格: view.backgroundColor = [UIColor or ...
- Python学习01 Hello World
Python学习之Hello World 准备工作 去官网http://www.python.org/ 下载python的安装包: http://www.python.org/download/ 当前 ...
- android之HttpClient
Apache包是对android联网访问封装的很好的一个包,也是android访问网络最常用的类. 下面分别讲一下怎么用HttpClient实现get,post请求. 1.Get 请求 HttpGet ...
- android Activity runOnUiThread() 方法使用
在android 中我们一般用 Handler 做主线程 和 子线程 之间的通信 . 现在有了一种更为简洁的写法,就是 Activity 里面的 runOnUiThread( Runnable )方法 ...
- Android判断屏幕开关状态
方法一:使用系统服务 PowerManager pm= (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); if(!pm. ...
- thinkphp 创建子应用
1 根目录建立 文件名 a 2 a 下建立index.php define('APP_NAME', 'a');define('APP_PATH', './a');define('RUNTIME_PAT ...
- Tomcat+Nginx+Lvs部署方案与性能调优
立项要求:用户登录并发数达到1000vuser.原项目设计没有Nginx和LVS,经过性能测试并发数最高到400,就报响应超时,且系统资源消耗严重.经过和架构师商议决定先加入Nginx解决负载均衡处理 ...
- nodejs events模块
var EventEmitter = require('events').EventEmitter; var emitter = new EventEmitter(); console.log(emi ...
- 转载文章----C#基础概念
转载地址:http://www.cnblogs.com/zhouzhou-aspnet/articles/2591596.html 1.值类型和引用类型 1.1堆和栈 简单的说值类型存放在堆栈上面,引 ...