Codeforces Round #756 (Div. 3) E2. Escape The Maze (hard version)
阿新 • • 發佈:2022-01-10
Codeforces Round #756 (Div. 3) E2題Escape The Maze (hard version)題解
題目
- 原題地址:E2. Escape The Maze (hard version)
- 題目編號:1611E2
- 目標演算法:深搜(dfs)、最短路、動態規劃(dp)
- 難度評分:1900
1.題目大意
- 基本的內容和 E1 一樣,只有問題不同
- 上一篇題解的連結如下:Codeforces Round #756 (Div. 3) E1. Escape The Maze (easy version)
- 問在給定的朋友中,最少幾人可以攔住小 V。
2.題目分析
- 在上一題的基礎上:
- 輸出為 YES 的情況無人可攔,輸出 -1;
- 輸出為 NO 的情況只需要選出:所有無人的葉子結點中,每個結點攔住小 V 的不同的朋友個數。
3.題目程式碼
#include <bits/stdc++.h> #define MAX 200005 using namespace std; const int INF = 0x3f3f3f3f; vector<int> e[MAX]; int dis[MAX], dp[MAX]; int ans = 0; void dfs(int u, int pre) { if(u != 1) dp[u] = dp[pre] + 1; for(int v: e[u]) if(v!=pre) dfs(v, u); } void dfs2(int u, int pre) { if(dis[u] == 0) return; int t = INF; for(int v: e[u]) { if(v==pre) continue; dfs2(v, u); t = min(t, dis[v]); } dis[u] = t + 1; } bool dfs3(int u, int pre) { if(dis[u]<=dp[u]) { ans++; return 0; } if(e[u].size()==1&&u!=1) return 1; bool f = 0; for(int v: e[u]) if(v!=pre) f |= dfs3(v, u); return f; } int main() { int t; cin >> t; while(t--) { int n, k; cin >> n >> k; for(int i=1;i<=n;i++) { dp[i] = 0; dis[i] = INF; e[i].clear(); } for(int i=1;i<=k;i++) { int t; cin >> t; dis[t] = 0; } for(int i=1;i<n;i++) { int u, v; cin >> u >> v; e[u].push_back(v); e[v].push_back(u); } dfs(1, 0); dfs2(1, 0); if(dfs3(1, 0)) cout << -1 << endl; else cout << ans << endl;; ans = 0; } }