码迷,mamicode.com
首页 > 其他好文 > 详细

[vijos1427]机密信息

时间:2016-10-25 19:24:36      阅读:258      评论:0      收藏:0      [点我收藏+]

标签:编号   开始   vijos   文件夹的名称   top   font   names   stream   stdin   

Description

技术分享有个很奇怪的习惯,他把他所有的机密信息都存放在一个叫机密盘的磁盘分区里,然而这个机密盘中却没有一个文件,那他是怎么存放信息呢?聪明的你一定想到了,技术分享的信息都是以文件夹名称的形式保存的。技术分享给机密盘中的每一个文件夹都编了号,而技术分享的机密信息是由技术分享文件夹转到技术分享文件夹的过程中必须经过的文件夹名称组合而成的(包括技术分享技术分享),由于技术分享的磁盘很慢,打开每个文件夹所耗费的时间等于该文件夹内下一级文件夹的数量。这次的任务是,给出每个文件夹的编号、名称以及它的父目录的编号和隐藏了技术分享机密信息的起始文件夹编号和终点文件夹编号,你要计算出来的是技术分享机密信息的长度以及寻找这个机密信息所需要的总时间。

Input

输入文件的第一行为技术分享个整数技术分享,分别代表文件夹的个数、起始文件夹编号、终点文件夹编号.

接下来技术分享行,每行有技术分享个整数技术分享技术分享个字符串技术分享(不包含空格),用空格分开,技术分享技术分享号文件夹的父目录编号(为技术分享时表示该文件夹为根目录下的一级文件夹),技术分享技术分享号文件夹的名称.

Output

输出文件共技术分享行,第一行是技术分享的机密信息的长度,第二行是所消耗的时间.

Sample Input

6 1 5
1 2 Lo
2 3 ra
3 0 .
4 3 bi
5 4 t
6 5 .COM

Sample Output

8
4

HINT

技术分享,保证一定有解.

假设你一开始就在初始文件夹位置,此时耗费的时间为0;你每打开一个文件夹,能够知道的文件夹名除了当前这个文件夹名之外,还有该文件夹内下一级的文件夹名.

Solution

这道题就是裸的技术分享...

只是有以下细节需要注意:

对于技术分享,不需要算技术分享的打开时间;有可能技术分享在一条链上.

#include<cmath>
#include<ctime>
#include<queue>
#include<stack>
#include<cstdio>
#include<vector>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#define K 15
#define M 305
#define N 10005
using namespace std;
struct graph{
    int nxt,to;
}e[N];
int f[N][K],g[N],l[N],fa[N],dep[N],chl[N],n,s,t,len,tim,cnt;
char c[M];stack<int> sta;
inline void addedge(int x,int y){
    e[++cnt].nxt=g[x];g[x]=cnt;e[cnt].to=y;
}
inline void dfs(int r){
    int u;dep[r]=1;sta.push(r);
    for(int i=0;i<K;++i)
        f[r][i]=r;
    while(!sta.empty()){
        u=sta.top();sta.pop();
        if(u!=r) for(int i=1;i<K;++i)
            f[u][i]=f[f[u][i-1]][i-1];
        for(int i=g[u];i;i=e[i].nxt){
            f[e[i].to][0]=u;
            sta.push(e[i].to);
            dep[e[i].to]=dep[u]+1;
        }
    }
}
inline int swim(int x,int h){
    for(int i=0;h;i++,h>>=1)
        if(h&1) x=f[x][i];
    return x;
}
inline int lca(int x,int y){
    if(dep[x]<dep[y]){
        int tem=x;x=y;y=tem;
    }
    x=swim(x,dep[x]-dep[y]);
    if(x==y) return x;
    int i;
    while(true){
        for(i=0;f[x][i]!=f[y][i];++i);
        if(!i) return f[x][0];
        x=f[x][i-1];y=f[y][i-1];
    }
}
inline void init(){
    scanf("%d%d%d",&n,&s,&t);
    for(int i=1,j,k;i<=n;++i){
        scanf("%d%d%s",&j,&k,c);
        addedge(k,j);
        l[j]=strlen(c);
        ++chl[k];fa[j]=k;
    }
    dfs(0);
    int k=lca(s,t);
    if(k!=s&&k!=t) tim=chl[k];
    len=l[k];
    for(int i=s;i!=k;i=fa[i]){
        len+=l[i];
        if(i!=s) tim+=chl[i];
    }
    for(int i=t;i!=k;i=fa[i]){
        len+=l[i];
        if(i!=t) tim+=chl[i];
    }
    printf("%d\n%d\n",len,tim); 
}
int main(){
    freopen("folder.in","r",stdin);
    freopen("folder.out","w",stdout);
    init();
    fclose(stdin);
    fclose(stdout);
    return 0;
}

[vijos1427]机密信息

标签:编号   开始   vijos   文件夹的名称   top   font   names   stream   stdin   

原文地址:http://www.cnblogs.com/AireenYe/p/5997421.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!