题意
输入
n
n
个文件的绝对路径,如果一个名为 的目录下只有一个
yy
y
y
的文件夹,则将这两层文件夹压缩成一个名为
xx−yy
x
x
−
y
y
的文件夹。求压缩后这
n
n
个文件的绝对路径。
1≤∑n个文件的绝对路径≤500000
1
≤
∑
n
个文件的绝对路径
≤
500000
思路
对于文件树的问题,比较令人头大的是不同父目录下文件名相同的文件,所以在判重时需要在同一父节点下,于是将边集
vector
v
e
c
t
o
r
和
map
m
a
p
合在一起,开一个
map
m
a
p
的边集数组
son
s
o
n
,其中
sonu
s
o
n
u
是
u
u
的子文件的 和其映射的
int
i
n
t
。
对于文件夹的 “
/
/
” 符号,通常化成“ ”直接用 读入最为方便。
代码
#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<sstream>
#include<map>
#define FOR(i,x,y) for(int i=(x);i<=(y);i++)
#define DOR(i,x,y) for(int i=(x);i>=(y);i--)
#define M 500003
#define N 10003
typedef long long LL;
using namespace std;
map<string,int>son[M];
string str[N],tmp;
int n,ID;
int main()
{
scanf("%d",&n);
FOR(i,1,n)
{
int u=0;
cin>>str[i];
FOR(j,0,(int)str[i].size()-1)if(str[i][j]=='/')str[i][j]=' ';
istringstream sin(str[i]);
while(sin>>tmp)
{
if(son[u].find(tmp)==son[u].end())son[u][tmp]=++ID;
u=son[u][tmp];
}
}
FOR(i,1,n)
{
string res="";
int u=0;
istringstream sin(str[i]);
while(sin>>tmp)
{
if(son[u].size()==1&&u)res+='-';
else res+='/';
res+=tmp;
u=son[u][tmp];
}
DOR(j,(int)res.size()-1,0)
{
if(res[j]=='/')break;
else if(res[j]=='-')
{
res[j]='/';
break;
}
}
cout<<res<<endl;
}
return 0;
}