算法1:(建树 + BFS求深度) $O(n)$
//先建树,在宽搜
#include <bits/stdc++.h>
using namespace std;
map<string, int> mp; //名字映射到数字
int id, st[110], old;
string ns[110];
vector<int> g[110];
int get(string s)
{
if (mp[s]) return mp[s];
mp[s] = ++id;
return mp[s];
}
void dfs(int u)
{
st[u] = 1;
for (int i = 0; i < g[u].size(); ++ i)
if (st[g[u][i]] == 0)
{
old ++;
dfs(g[u][i]);
old++;
}
}
int bfs(int u)
{
//维护出最大层次,在乘以2
queue<int> q;
memset(st, 0, sizeof st);
q.push(u);
st[u] = 1;
int deep = 0;
while (q.size())
{
deep++;
int len = q.size();
for (int i = 0; i < len; ++ i)
{
int t = q.front(); q.pop();
for (int j = 0; j < g[t].size(); ++ j)
if (st[g[t][j]] == 0)
{
q.push(g[t][j]);
st[g[t][j]] = 1;
}
}
}
// cout << endl << "shendu: " << deep-1 << endl;
return (deep-1) * 2 * 10;
}
int main()
{
int T, n;
cin >> T;
while (T--)
{
cin >> n;
for (int i = 0; i < n; ++ i) cin >> ns[i];
for (int i = 0; i < n; ++ i) g[i].clear();
mp.clear();
id = 0;
mp[ns[n-1]] = ++id; //根节点映射成1
memset(st, 0, sizeof st);
old = 0;
for (int i = 0, a = id; i < n; ++ i)
{
int b = get(ns[i]); //获取当前名字映射的数
g[a].push_back(b);
a = b;
}
dfs(1);
cout << old * 10 - bfs(1) << endl;
}
return 0;
}
算法2:(建树 + dfs求深度) $O(n)$
//先建树,在宽搜
#include <bits/stdc++.h>
using namespace std;
map<string, int> mp; //名字映射到数字
int id, st[110], old, dep;
string ns[110];
vector<int> g[110];
int get(string s)
{
if (mp[s]) return mp[s];
mp[s] = ++id;
return mp[s];
}
void dfs(int u)
{
st[u] = 1;
for (int i = 0; i < g[u].size(); ++ i)
if (st[g[u][i]] == 0)
{
old ++;
dfs(g[u][i]);
old++;
}
}
//维护从根的最深层次
void dfs2(int u, int cur)
{
st[u] = 1;
dep = max(dep, cur);
for (int i = 0; i < g[u].size(); ++ i)
if (!st[g[u][i]])
dfs2(g[u][i], cur+1);
st[u] = 0;
}
int main()
{
int T, n;
cin >> T;
while (T--)
{
cin >> n;
for (int i = 0; i < n; ++ i) cin >> ns[i];
for (int i = 0; i < n; ++ i) g[i].clear();
mp.clear();
id = 0;
mp[ns[n-1]] = ++id; //根节点映射成1
memset(st, 0, sizeof st);
old = dep = 0;
for (int i = 0, a = id; i < n; ++ i)
{
int b = get(ns[i]); //获取当前名字映射的数
g[a].push_back(b);
a = b;
}
dfs(1);
memset(st, 0, sizeof st);
dfs2(1, 1);
cout << old * 10 - (dep-1) * 20 << endl;
}
return 0;
}