洛谷的文件夹(树形结构+DFS+字符串哈希)

来源:互联网 发布:97网络含义是什么 编辑:程序博客网 时间:2024/06/04 19:55

洛谷的文件夹

Luogu P1738

题目描述

kkksc03是个非凡的空想家!在短时间内他设想了大量网页,然后总是交给可怜的lzn去实现。
洛谷的网页端,有很多文件夹,文件夹还套着文件夹。
例如:/luogu/application/controller表示根目录下有一个名称为luogu的文件夹,这个文件夹下有一个名称application的文件夹,其中还有名为controller的文件夹。
每个路径的第1个字符总是’/’,且没有两个连续的’/’,最后的字符不是’/’。所有名称仅包含数字和小写字母。
目前根目录是空的。kkksc03想好了很多应该有的文件夹路径名。问题是,需要是使这些文件夹都存在,需要新建几个文件夹呢?

输入输出格式

输入格式:
输入文件第1行为一个正整数N。
接下来N行,每行为一个描述路径的字符串,长度均不超过100。

输出格式:
输出应包含N行,每行1个正整数,第i行输出若要使第1个路径到第i个路径存在,最少需要新建多少个文件夹。

样例输入1:
2
/luogu/application/controller
/luogu/application/view

样例输入2:
3
/chicken
/chicken/egg
/chicken

样例输入3:
4
/a
/a/b
/a/c
/b/b

样例输出1:
3
4

样例输出2:
1
2
2

样例输出3:
1
2
3
5

说明
数据规模:
对于所有数据,N<=1000。
对于20%数据,有N<=20;
对于50%数据,有N<=200;

对于30%数据,有对于所有路径最多存在两个’/’(包含第1个字符)。

思路

首先,我们应该注意到这是一个树形结构,这个我们可以结合Trie树来理解,我们在处理每一个路径的时候,要把每一个“/”分隔开的子字符串处理成哈希数。
然后对于之前不存在的节点,就加一个节点来处理。如果存在,那我们就顺着它向下DFS,统计总更新的节点数。
需要注意的一点就是,要开一个超级根节点来连接第一等级。

代码

#include<iostream>#include<cstdio>#include<cstdlib>#include<algorithm>#include<cstring>#include<set>using namespace std;long long i,j,m,n,temp,tot,len,modd=23333333333;string s;long long hd[100001],cnt,cc;long long par[101];struct data{    long long y,nxt,chr;}a[100001];long long r(){    long long ans=0,f=1;    char ch=getchar();    while(ch<'0'||ch>'9')    {        if(ch=='-')        f=-1;        ch=getchar();    }    while(ch>='0'&&ch<='9')    {        ans*=10;        ans+=ch-'0';        ch=getchar();    }    return ans*f;}void dfs(long long x,long long t){    long long kk=0;    if(t==cnt+1) return;    for(long long p=hd[x];p;p=a[p].nxt)    {        if(par[t]==a[p].chr)        {            dfs(a[p].y,t+1);            kk=1;            break;        }    }    if(!kk)    {        a[++temp].chr=par[t];        a[temp].nxt=hd[x];        a[temp].y=++tot;        hd[x]=temp;        dfs(tot,t+1);    }}int main(){    n=r();    ++temp;    tot++;    for(i=1;i<=n;i++)    {        cin>>s;        len=s.size();        cnt=0,cc=0;        for(j=1;j<len;j++)        {            if(s[j]=='/')            par[++cnt]=cc,cc=0;            else            cc*=13131,cc%=modd,cc+=s[j];        }        par[++cnt]=cc;        dfs(1,1);        cout<<tot-1<<endl;    }    return 0;}/*2/luogu/application/controller/luogu/application/view*/

这里写图片描述

原创粉丝点击