一本通1581旅游规划

1581:旅游规划

时间限制: 1000 ms         内存限制: 524288 KB

描述
W市的交通规划出现了重大问题,市政府下决心在全市的各大交通路口安排交通疏导员来疏导密集的车流。但由于人员不足,W市市长决定只在最需要安排人员的路口安放人员。具体说来,W市的交通网络十分简单,它包括n个交叉路口和n-1条街道,任意一条街道连接两个交叉路口,并且任意两个交叉路口之间都存在一条路径互相连接。经过长期调查结果显示如果一个交叉路口位于W市交通网的最长路径上,那么这个路口必然拥挤不堪,所谓最长路径定义为某条路径p=(v1,v2,v3…vk),路径经过的路口各不相同且城市中不存在长度>k的路径(因此可能存在着不唯一的最长路径)。因此W市市长希望知道有哪些路口位于城市交通网的最长路径之上。

格式
输入格式
第一行包括一个整数n。

之后的n-1行每行包括两个整数u, v表示编号为u和v的路口之间存在着一条街道(注意:路口被依次编号为0到n-1)

输出格式
输出包括若干行,每行包括一个整数——某个位于最长路上路口的编号。

为了确保解唯一,我们规定位于所有最长路上的路口按编号顺序从小到大输出。

样例1
样例输入1
10
0 1
0 2
0 4
0 6
0 7
1 3
2 5
4 8
6 9
样例输出1
0
1
2
3
4
5
6
8
9
提示
这里存在着若干条最长路径,其中的两条是3-1-0-2-5与8-4-0-6-9,他们的长度都是5,但是不存在长度>5的路径且所有最长路径都不包括路口7,所以答案中没有7。

数据范围:
对于50%的数据保证n<=1000
对于100%的数据保证n<=200000

先附上手绘的样例图(过于丑陋)

sol:一开始想求出直径的两个端点然后差分搞一下,然后发现非常wei,然后就想到如果一点在直径上,那么他不是只有两个方向延伸吗?(向儿子,或者向上爬几步爬到根或者爬到别的子树里去);所以两遍dfs就可以求出两个方向的最长值,还有注意下因为Up[x]=max(Up[fa]+1,Down[fa]+1),但是如果Down[fa]最大值就是x转移过来的话,要用Down[fa]的次大值来转移,所以Down要记录Zd和Cd

#include <bits/stdc++.h>
using namespace std;
inline int read()
{
    int s=0;
    bool f=0;
    char ch=‘ ‘;
    while(!isdigit(ch))
    {
        f|=(ch==‘-‘);
        ch=getchar();
    }
    while(isdigit(ch))
    {
        s=(s<<3)+(s<<1)+(ch^48);
        ch=getchar();
    }
    return (f)?(-s):(s);
}
#define R(x) x=read()
inline void write(int x)
{
    if(x<0)
    {
        putchar(‘-‘);
        x=-x;
    }
    if(x<10)
    {
        putchar(x+‘0‘);
        return;
    }
    write(x/10);
    putchar((x%10)+‘0‘);
    return;
}
inline void writeln(int x)
{
    write(x);
    putchar(‘\n‘);
    return;
}
#define W(x) write(x),putchar(‘ ‘)
#define Wl(x) writeln(x)
const int N=200005,M=400005;
int n;
struct Tree
{
    int tot,Next[M],to[M],head[N];
    inline void add(int x,int y)
    {
        Next[++tot]=head[x];
        to[tot]=y;
        head[x]=tot;
        return;
    }
    int Down_Zd[N],From_Zd[N],Down_Cd[N],From_Cd[N];
    inline void dfs_Down(int x,int fa)
    {
        int i;
        for(i=head[x];i;i=Next[i]) if(to[i]!=fa)
        {
            dfs_Down(to[i],x);
            if(Down_Zd[to[i]]+1>Down_Zd[x])
            {
                From_Cd[x]=From_Zd[x];
                Down_Cd[x]=Down_Zd[x];
                From_Zd[x]=to[i];
                Down_Zd[x]=Down_Zd[to[i]]+1;
            }
            else if(Down_Zd[to[i]]+1>Down_Cd[x])
            {
                From_Cd[x]=to[i];
                Down_Cd[x]=Down_Zd[to[i]]+1;
            }
        }
        return;
    }
    int Up[N];
    inline void dfs_Up(int x,int fa)
    {
        if(fa)
        {
            if(From_Zd[fa]!=x) Up[x]=max(Up[fa]+1,Down_Zd[fa]+1);
            else Up[x]=max(Up[fa]+1,Down_Cd[fa]+1);
        }
        int i;
        for(i=head[x];i;i=Next[i]) if(to[i]!=fa)
        {
            dfs_Up(to[i],x);
        }
        return;
    }
    inline void Output()
    {
        int i,ans=0;
        for(i=1;i<=n;i++) ans=max(ans,(Down_Zd[i]+Up[i],Down_Zd[i]+Down_Cd[i]));
        for(i=1;i<=n;i++)
        {
//            printf("@ %d %d\n",Down_Zd[i],Up[i]);
            if((Down_Zd[i]+Up[i]==ans)||(Down_Zd[i]+Down_Cd[i]==ans)) Wl(i-1);
        }
        return;
    }
    inline void Init()
    {
        tot=0;
        memset(head,0,sizeof head);
        return;
    }
}T;
int main()
{
    int i;
    T.Init();
    R(n);
    for(i=1;i<n;i++)
    {
        int x,y;
        x=read()+1; y=read()+1;
        T.add(x,y); T.add(y,x);
    }
    T.dfs_Down(1,0);
    T.dfs_Up(1,0);
    T.Output();
    return 0;
}
/*
input
10
0 1
0 2
0 4
0 6
0 7
1 3
2 5
4 8
6 9
output
0
1
2
3
4
5
6
7
8
9
*/

原文地址:https://www.cnblogs.com/gaojunonly1/p/10356689.html

时间: 2024-11-08 09:33:39

一本通1581旅游规划的相关文章

07-图6 旅游规划

题目: 有了一张自驾旅游路线图,你会知道城市间的高速公路长度.以及该公路要收取的过路费.现在需要你写一个程序,帮助前来咨询的游客找一条出发地和目的地之间的最短路径.如果有若干条路径都是最短的,那么需要输出最便宜的一条路径. 输入格式: 输入说明:输入数据的第1行给出4个正整数N.M.S.D,其中N(2≤N≤500)是城市的个数,顺便假设城市的编号为0~(N?1):M是高速公路的条数:S是出发地的城市编号:D是目的地的城市编号.随后的M行中,每行给出一条高速公路的信息,分别是:城市1.城市2.高速

PAT 旅游规划

旅游规划 有了一张自驾旅游路线图,你会知道城市间的高速公路长度.以及该公路要收取的过路费.现在需要你写一个程序,帮助前来咨询的游客找一条出发地和目的地之间的最短路径.如果有若干条路径都是最短的,那么需要输出最便宜的一条路径. 考察dijkstra算法   要注意的是  当权重相等时 要更新下费用 AC代码 1 #include <stdio.h> 2 #define MAX 100000 3 typedef struct 4 { 5 int weight; 6 int cost; 7 }gra

PTA 旅游规划(25 分)

7-10 旅游规划(25 分) 有了一张自驾旅游路线图,你会知道城市间的高速公路长度.以及该公路要收取的过路费.现在需要你写一个程序,帮助前来咨询的游客找一条出发地和目的地之间的最短路径.如果有若干条路径都是最短的,那么需要输出最便宜的一条路径. 输入格式: 输入说明:输入数据的第1行给出4个正整数N.M.S.D,其中N(2≤N≤500)是城市的个数,顺便假设城市的编号为0~(N?1):M是高速公路的条数:S是出发地的城市编号:D是目的地的城市编号.随后的M行中,每行给出一条高速公路的信息,分别

如何做好农业观光旅游规划和农业休闲旅游开发?

熊大寻旅游规划公司/文 农业旅游是一种新型农业生产经营形式 ,也是一种新型旅游活动项目 ,是在发展农业生产的基础上有机地附加了生态旅游观光功能的交叉性产业 ,是当今旅游新需求的必然产物.农业生态旅游是把农业.生态和旅游业结合起来,利用田园景观.农业生产活动.农村生态环境和农业生态经营模式,吸引游客前来观赏.品尝.作习.体验.健身.科学考察.环保教育.度假.购物的一种新型的旅游开发类型.生态农业旅游是近几年才兴起的一种新型的旅游方式,人们多居住在城市里面,对于农村的概念越来越模糊.所以根据人们返璞

loj10159. 「一本通 5.2 练习 2」旅游规划

思路: 树形dp,最后用dfs标记所有的路径上的点,要注意可能会有多个点在以它为根的子树中的最长路径等于整棵树的最长路径,要分别作为初始点遍历整棵树. #include<cstdio> #include<iostream> #include<cstdlib> #include<vector> using namespace std; const int maxn = 200010; void qread(int &x) { x = 0; regist

vijos 1476 旅游规划(csapc)

描述 W市的交通规划出现了重大问题,市政府下决心在全市的各大交通路口安排交通疏导员来疏导密集的车流.但由于人员不足,W市市长决定只在最需要安排人员的路口安放人员.具体说来,W市的交通网络十分简单,它包括n个交叉路口和n-1条街道,任意一条街道连接两个交叉路口,并且任意两个交叉路口之间都存在一条路径互相连接.经过长期调查结果显示如果一个交叉路口位于W市交通网的最长路径上,那么这个路口必然拥挤不堪,所谓最长路径定义为某条路径p=(v1,v2,v3-vk),路径经过的路口各不相同且城市中不存在长度>k

PAT 07-图6 旅游规划 (25分)

有了一张自驾旅游路线图,你会知道城市间的高速公路长度.以及该公路要收取的过路费.现在需要你写一个程序,帮助前来咨询的游客找一条出发地和目的地之间的最短路径.如果有若干条路径都是最短的,那么需要输出最便宜的一条路径. 输入格式: 输入说明:输入数据的第1行给出4个正整数NN.MM.SS.DD,其中NN(2\le N\le 5002≤N≤500)是城市的个数,顺便假设城市的编号为0~(N-1N−1):MM是高速公路的条数:SS是出发地的城市编号:DD是目的地的城市编号.随后的MM行中,每行给出一条高

旅游规划

试题描述 W 市的交通规划出现了重大问题,市政府下定决心在全市各大交通路口安排疏导员来疏导密集的车流.但由于人员不足,W 市市长决定只在最需要安排人员的路口安排人员.具体来说,W 市的交通网络十分简单,由 n 个交叉路口和 n−1 条街道构成,交叉路口路口编号依次为 0,1,?,n−1 .任意一条街道连接两个交叉路口,且任意两个交叉路口间都存在一条路径互相连接. 经过长期调查,结果显示,如果一个交叉路口位于 W 市交通网最长路径上,那么这个路口必定拥挤不堪.所谓最长路径,定义为某条路径 p=(v

07-图6 旅游规划 (25 分)

有了一张自驾旅游路线图,你会知道城市间的高速公路长度.以及该公路要收取的过路费.现在需要你写一个程序,帮助前来咨询的游客找一条出发地和目的地之间的最短路径.如果有若干条路径都是最短的,那么需要输出最便宜的一条路径. 输入格式: 输入说明:输入数据的第1行给出4个正整数N.M.S.D,其中N(2)是城市的个数,顺便假设城市的编号为0~(N?1):M是高速公路的条数:S是出发地的城市编号:D是目的地的城市编号.随后的M行中,每行给出一条高速公路的信息,分别是:城市1.城市2.高速公路长度.收费额,中