题解:P9648 [SNCPC2019] Unrooted Trie

· · 题解

前言:

我是入机,模拟赛题解看不懂一点,最后学了 zjh 大佬做法也是一看就懂了。

分析:

可以考虑换根 \text{dp}。设 dp_i 表示以 i 为根的子树中有没有重复的,那么首先判掉一定无解的情况:

把这个判掉之后还要考虑:

那么 \text{dp} 方程也就自然而然的出来了。

dp_{now} = \left\{\begin{matrix} 0& \exists s_{x\in{son}} > \text{2} \\ \min_{} \{dp_{x\in{son}}\} & \text{otherwise} & \end{matrix}\right. 当把子树搜完之后,记得还原最初的 $\text{dp}$ 数表的值,不然会影响到下次换根。 ```cpp // EXpert实力! # include <bits/stdc++.h> # define pb push_back # define cl clear using namespace std; const int N = 2e5 + 5; int n; struct node { int v; char w; }; vector <node> g[N] ; int vec[N],cnt;//vec记录方案 int mp[N][27]; bool dp[N]; void pre_dfs (int now , int fa) { dp[now] = 1; for (auto x : g[now]) { if (x.v == fa) continue; pre_dfs (x.v , now); dp[now] &= dp[x.v]; mp[now][x.w - 'a'] ++; } for (int i = 0;i < 26;++i) if (mp[now][i] > 1) dp[now] = 0; } void cgroot (int now , int fa , int op ,int EX, int pert, char pre) { mp[now][pre - 'a'] += op, mp[fa][pre - 'a'] -= op; dp[now] = dp[fa] = 1; if (op == -1) return dp[now] = EX , dp[fa] = pert,void(); for (int i = 0;i < 26;++i) { if (mp[now][i] > 1) dp[now] = 0; if (mp[fa][i] > 1) dp[fa] = 0; } for (auto x : g[fa]) if (x.v != now) dp[fa] &= dp[x.v]; for (auto x : g[now]) dp[now] &= dp[x.v]; if (dp[now] && op == 1) vec[++cnt] = now; } void dfs (int now,int fa ,char pre) { int EX = dp[now],pert = dp[fa]; if (now != 1) cgroot(now , fa , 1 ,EX , pert ,pre); for (auto x : g[now]) if (x.v != fa) dfs (x.v , now , x.w); if (now != 1) cgroot (now , fa , -1 ,EX , pert , pre); } void solve () { bool Lian = 1; cnt = 0; cin >> n; memset (dp,0,sizeof dp); memset (mp,0,sizeof mp); for (int i = 1;i <= n;++i) g[i].cl(); for (int i = 1;i < n;++i) { int u,v; char w; cin >> u >> v >> w , g[u].pb(node {v,w} ) , g[v].pb(node {u,w} ); } pre_dfs (1 , -1); if (dp[1]) ++cnt; dfs (1 , -1 , -1); cout << cnt << "\n"; return void(); } signed main () { ios::sync_with_stdio(false); cin.tie (0); cout.tie (0); int T; cin >> T; while (T -- >0) solve (); return 0; } /* 5 1 2 a 1 3 a 3 4 b 4 5 c */ ``` upd:添加了对"入机"一词的解释,免得被认为是错别字。