题解 P1738 洛谷的文件夹
类似 \(Trie\) 树,如果前缀相同则直接下跳,否则新建节点。但是注意这里的节点所存内容较多,建议离散化后用 \(pair\) 存储,便于配对。
#include <bits/stdc++.h>
using namespace std;
#define N 100010
template <class T>
inline void read(T &a){
T x = 0, s = 1;
char c = getchar();
while (!isdigit(c)) { if (c == '-') s = -1; c = getchar();}
while (isdigit(c)){x = (x * 10) + (c ^ '0'); c = getchar();}
a = x * s;
return ;
}
int T;
map<string, int> g;
int top = 0;
vector<int> G;
struct Tree{
struct node{
vector< pair<int, int> > H;
} t[N];
int ans = 0, p, q;
inline void clean(){
this->p = 0;
this->q = 0;
return ;
}
Tree(){
this->ans = 0;
return;
}
void main(){ // x 为目标添加编号
this->p = 0;
this->q = 0; // 0号作为初始节点
while (q < G.size()){
bool flag = 0;
int now = 0;
for (int i = 0; i < t[p].H.size(); i++){
if (t[p].H[i].first == G[q]){
flag = 1;
now = i;
break;
}
}
if (flag){
p = t[p].H[now].second;
q++;
}
else{ // 新建
t[p].H.push_back(make_pair(G[q], ++ans));
p = ans;
q++;
}
}
return ;
}
} tree;
inline void clean(){
G.clear();
tree.clean();
return ;
}
int main(){
// freopen("hh.txt", "r", stdin);
read(T);
while (T--){
clean();
string s;
cin >> s;
int p = 1; // 开头斜杠过滤掉
string temp = "";
while (p < s.length()){
if (s[p] == '/'){ // 分界点
if (!g[temp])
g[temp] = ++top;
p++;
G.push_back(g[temp]);
continue;
}
temp += s[p];
p++;
}
if(!g[temp]) g[temp] = ++top;
G.push_back(g[temp]);
tree.main();
printf("%d\n", tree.ans);
// 处理完总语句之后
}
return 0;
}