Codeforces Round #756 div3
date:2021/11/28
题目大意:
在一棵有根无向树中玩游戏,位于根节点 1 的 vlad 能否避开朋友们的阻拦到达任意根节点;
朋友们位于树上不同的结点上;
阻拦
:他们同时移动,若在同一顶点相遇,或先vlad到达他要到达的结点,即半路拦截;
思路
参考思路
假设朋友所在的点为被tag的点;
通过观察可以发现,存在一个叶子结点使得根节点到它的距离,小于所有tag结点到它的最小距离;
那么就为 yes;
另一种思路就是,对于根节点要经过的点比较深度(等价根节点到该节点的距离)与 所有tag到该结点的 d i s m i n dis_{min} dismin;若深度大于 d i s m i n dis_{min} dismin,则此路不同,一直比较到根节点到达叶子节点,若到达不了即输出no,否则输出yes。详细代码解释qwq;
code
// Problem: E1. Escape The Maze (easy version)
// Contest: Codeforces - Codeforces Round #756 (Div. 3)
// URL: https://codeforces.com/contest/1611/problem/E1
// Memory Limit: 256 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)
#include<bits/stdc++.h>
using namespace std;
#define _orz ios::sync_with_stdio(false),cin.tie(0)
#define mem(str,num) memset(str,num,sizeof(str))
#define forr(i,a,b) for(int i = a;i <= b;i++)
#define forn(i,n) for(int i = 0; i < n; i++)
#define all(a) (a.begin(),a.end())
#define dbg() cout << "0k!" << endl;
//#define _DEBUG
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int N = 2e5+10;
const ll MOD = 1e9+7;
bool tag[N];
vector<int> e[N];
int d[N],dis[N],ok;
int n,k;
void dfs(int u ,int fa){
if(tag[u]){
dis[u] = 0;
return;
}
for(auto it:e[u]){
if(it == fa) continue;
d[it] = d[u]+1;
dfs(it,u);// 从下往上搜;
dis[u] = min(dis[u],dis[it]+1); // 找tag点到u的最小距离;
}
}
void dfs1(int u,int fa){
if(d[u] >= dis[u]) return; // 深度大于距离 就放弃这条路
if(e[u].size() == 1 && u != 1) ok = 1; // 到达叶子结点惹;
for(auto it:e[u]){
if(it == fa) continue;
dfs1(it,u);
}
}
void init(){
ok = 0;
forr(i,0,n) e[i].clear(),dis[i] = inf,d[i] = 0,tag[i] = 0;
}
void so1ve(){
cin >> n >> k;
init();
while(k--){
int x; cin >> x;
tag[x] = 1;
}
forr(i,1,n-1){
int u,v;cin >> u >> v;
e[u].push_back(v);
e[v].push_back(u);
}
d[1] = 0;
dfs(1,0);
dfs1(1,0);
if(ok) puts("yes");
else puts("no");
}
int main()
{
#ifdef _DEBUG
//freopen("input.txt","r",stdin);
freopen("out.txt","w",stdout);
#endif
int t; cin >> t;
while(t--) so1ve();
return 0;
}
如有错误希望指出!!!
orz
D2的话就是在dfs1的基础上更改:
int dfs2(int u,int fa){
int ret = 0;
// 当u可以拦截时就++,表明存在一个tag拦截了vald;!!
if(d[u] >= dis[u]){
return 1;
}
for(auto it:e[u]){
if(it == fa) continue;
ret += dfs2(it,u);
}
return ret;
}