Aizu 2677 Breadth-First Search by Foxpower LCA+bfs

A - Breadth-First Search by Foxpower

Problem Statement

Fox Ciel went to JAG Kingdom by bicycle, but she forgot a place where she parked her bicycle. So she needs to search it from a bicycle-parking area before returning home.

The parking area is formed as a unweighted rooted tree TT with nn vertices, numbered 11 through nn. Each vertex has a space for parking one or more bicycles. Ciel thought that she parked her bicycle near the vertex 11, so she decided to search it from there by the breadth-first search. That is, she searches it at the vertices in the increasing order of their distances from the vertex 11. If multiple vertices have the same distance, she gives priority to the vertices in the order of searching at their parents. If multiple vertices have the same parent, she searches at the vertex with minimum number at first.

Unlike a computer, she can‘t go to a next vertex by random access. Thus, if she goes to the vertex jj after the vertex ii, she needs to walk the distance between the vertices ii and jj. BFS by fox power perhaps takes a long time, so she asks you to calculate the total moving distance in the worst case starting from the vertex 11.

Input

The input is formatted as follows.

nn
p2p2 p3p3 p4p4 ?? pnpn

The first line contains an integer nn (1≤n≤1051≤n≤105), which is the number of vertices on the unweighted rooted tree TT. The second line contains n−1n−1 integers pipi (1≤pi<i1≤pi<i), which are the parent of the vertex ii. The vertex 11 is a root node, so p1p1 does not exist.

Output

Print the total moving distance in the worst case in one line.

Sample Input 1

4
1 1 2

Output for the Sample Input 1

6

Sample Input 2

4
1 1 3

Output for the Sample Input 2

4

Sample Input 3

11
1 1 3 3 2 4 1 3 2 9

Output for the Sample Input 3

25思路:求出出队序列,两两求树内最近距离;
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mod 1000000007
#define esp 0.00000000001
const int N=2e5+10,M=1e6+10,inf=1e9;
#define mem(s) memset(s,0,sizeof(s))
int n,m,head[N],t,vis[N],deep[N],fa[N][20];
int a[N];
int flag[N];
struct ss {
  int to,next;
}e[N*2];
void add(int u,int v) {
   e[t].next=head[u];e[t].to=v;head[u]=t++;
}
void init() {
  t=1;mem(head);mem(vis);mem(fa);mem(deep);mem(flag);
}
void dfs(int x) {
    vis[x]=1;
    for (int i=1; i<=18 ;i++) {
        if(deep[x]<(1<<i)) break;
        fa[x][i] = fa[fa[x][i-1]][i-1];
    }
    for (int i=head[x];i;i=e[i].next) {
        if(vis[e[i].to]) continue;
        deep[e[i].to]=deep[x]+1;
        fa[e[i].to][0]=x;
        dfs(e[i].to);
    }
}
int RMQ_LCA(int x,int y) {
    if(deep[x]<deep[y]) swap(x,y);
    int d=deep[x]-deep[y];
    for (int i=0; i<=18 ;i++)
        if((1<<i)&d) x=fa[x][i];
    for (int i=18; i>=0 ;i--) {
        if(fa[x][i]!=fa[y][i]) {
            x=fa[x][i];y=fa[y][i];
        }
    }
    if(x==y) return x;
    else return fa[x][0];
}
int Dis_LCA(int x,int y) {
    int LCA= RMQ_LCA(x,y);
    return (deep[x]+deep[y]-2*deep[LCA]);
}
struct is
{
    int pos,step,pre;
};
int main()
{
    int x,y,z,i,t;
    while(~scanf("%d",&x))
    {
        queue<is>q;
        init();
        for(i=2;i<=x;i++)
        scanf("%d",&a[i]);
        for(i=x;i>=2;i--)
        {
            add(a[i],i);
            add(i,a[i]);
        }
        dfs(1);
        int maxdeep=0;
        int pre=0;
        is st;
        st.pos=1;
        st.step=0;
        st.pre=0;
        q.push(st);
        flag[1]=1;
        ll ans=0;
        while(!q.empty())
        {
            is vv=q.front();
            q.pop();
            if(vv.pos!=1)
            {
                ans+=Dis_LCA(vv.pos,pre);
            }
            pre=vv.pos;
            maxdeep=vv.step;
            int pos=vv.pos;
            for(i=head[vv.pos];i;i=e[i].next)
            {
                if(flag[e[i].to])
                continue;
                is en;
                en.pos=e[i].to;
                en.step=vv.step+1;
                en.pre=vv.pos;
                flag[e[i].to]=1;
                q.push(en);
            }
        }
        printf("%lld\n",ans);
    }
    return 0;
}
时间: 2024-08-24 23:00:47

Aizu 2677 Breadth-First Search by Foxpower LCA+bfs的相关文章

#7 div1 A Breadth-First Search by Foxpower 在线LCA(倍增),模拟

A - Breadth-First Search by Foxpower Time Limit:2000MS     Memory Limit:131072KB     64bit IO Format:%lld & %llu Submit Status Description A - Breadth-First Search by Foxpower Problem Statement Fox Ciel went to JAG Kingdom by bicycle, but she forgot

图的遍历之广度优先搜索(Breadth First Search)

描述 广度优先搜索算法(Breadth First Search)与树的层序遍历(level-order traversal)类似,基本思想是思想是: 从图中某顶点v出发,访问v之后,并将其访问标志置为已被访问,即visited[i]=1: 依次访问v的各个未曾访问过的邻接点: 分别从这些邻接点出发依次访问它们的邻接点,并使得"先被访问的顶点的邻接点先于后被访问的顶点的邻接点被访问,直至图中所有已被访问的顶点的邻接点都被访问到: 如果此时图中尚有顶点未被访问,则需要另选一个未曾被访问过的顶点作为

BFS—— Breadth First Search 广度优先算法

Breadth First Search BFS家伙还是很有用的,特地从wiki扒了一个动态的图,来帮助感性的理解这个动态搜索的过程. 对于如下一个无权值的有向图,在进行广度优先搜索呢?这里我们的代码实现是,以节点3为入口 对于BFS的理论基础介绍,个人觉得还是看<DSAA>比较好.这里不做介绍,注重分析该搜索算法的实现. 如果对于图这种数据结构不熟悉,这个BFS一般是搞不定的... 下面分别是无向图的邻接表实现和邻接矩阵实现 http://blog.csdn.net/cinmyheart/a

LeetCode Lowest Common Ancestor of a Binary Search Tree (LCA最近公共祖先)

题意:给一棵二叉排序树,找p和q的LCA. 思路:给的是排序树,那么每个节点必定,大于左子树中的最大,小于右子树种的最小.根据这个特性,找LCA就简单多了. 三种情况: (1)p和q都在root左边,那么往root左子树递归. (2)在右同理. (3)一左一右的,那么root->val肯定大于其中的1个,小于另一个. 1 /** 2 * Definition for a binary tree node. 3 * struct TreeNode { 4 * int val; 5 * TreeNo

Breadth First Search VS Depth First Search (Algorithms)

First lets recall the concept for BFS and DFS. I will use below Binary Tree as an example. Before that, lets go through some of the concepts of Trees and Binary Trees quickly. Concept of Binary Trees A binary tree is made of nodes, where each node co

(总结)宽度优先搜索(Breadth First Search)

ACM入门最经典的开局一般都是宽搜. 宽度优先搜索(以下均简称bfs)一般用于树和图的搜索,在ACM中属于比较基础的技巧,因此需要非常熟练的掌握. 那么从最基础的bfs开始讲起.在一个迷宫中,有一个起点和一个终点(出口),和一些障碍物(无法通过). 比如下图

Chapter four Breadth First Search(宽度优先搜索)

BFS最主要的数据结构是Queue,由LinkedList实现. 1.binary-tree-level-order-traversal(二叉树的层次遍历) 给出一棵二叉树,返回其节点值的层次遍历(逐层从左往右访问) BFS解法[基本模板]: public class Solution { /** * @param root: The root of binary tree. * @return: Level order a list of lists of integer */ public

图论算法(5) --- 双向广搜求最短路(Bidirectional Breadth First Search)

我们知道,在图论算法中,求最短路是最基本的问题.在求最短路的问题中,应用双向广度优先搜索算法,又是一个较为高效而又简单的算法.所谓双向广度优先搜索,其实根本的核心还是BFS,只不过它是从起点和终点两头同时搜索,大大提高了搜索效率,又节省了搜索空间.广搜大家知道当然是用队列来实现了,在这里,要注意的问题就是,我们必须按层搜索,正向队列处理一层,接着去处理反向队列的一层,按层交替进行,而不是按节点交替进行,这点需要注意,其他的也就很简单了,代码中附有注释,如有问题请留言. package simil

Codevs1026 SEARCH(逃跑的拉尔夫 )(BFS)

SEARCH 时间限制: 1 Sec  内存限制: 128 MB提交: 11  解决: 4[提交][状态][讨论版] 题目描述 年轻的拉尔夫开玩笑地从一个小镇上偷走了一辆车,但他没想到的是那辆车属于警察局,并且车上装有用于发射车子移动路线的装置. 那个装置太旧了,以至于只能发射关于那辆车的移动路线的方向信息. 编写程序,通过使用一张小镇的地图帮助警察局找到那辆车.程序必须能表示出该车最终所有可能的位置. 小镇的地图是矩形的,上面的符号用来标明哪儿可以行车哪儿不行.“.”表示小镇上那块地方是可以行