题目大意:
2*n的点阵,问能否画出题中给出的树,且树边不交叉。
解题思路:
一开始不会……后来问了老司机……
分成四种点进行讨论。
所有叶子节点都是4,然后向上递推。
至于如何寻找根节点:
因为第一种节点最多只有一个,所以先把默认的1号点当根来搜叶子标四号点。
这样的话,如果递推出了好多个①点,那就是no。
如果只递推出了一个①点,那这个①点就是根。
就以递推出来的①点为根重新做一遍dp,看看是否满足条件。
如果连①点都没搜出来的话,就说明随便当根怎么画都能满足条件了。就肯定是yes。
后来在cf的提交里看到了个特别有意思的代码……
过了但是我看不懂……求老司机教教我……
/*
──────────────────────────────────────
─▄▄▄───────────▄▄▄▄▄▄▄────────────────
█▀░▀█──────▄▀▀▀░░░░░░░▀▀▄▄────────────
█░░░░█───▄▀░░░░░░░░░░░░░░░▀▄───────▄▄▄
█▄░░░▀▄▄▀░░██░░░░░░░░░░░░░░▀█────█▀▀░█
─█░░░░█▀░░░▀░░░░░░░░██░░░░░░▀█─▄█░░░░█
─▀█░░▄█░░░░░░░▄▄▄░░░░▀░░░░░░░███░░░░█▀
──█▄░█░░░░░▄███████▄░░░░░░░░░█▀░░░░▄▀─
──▀█░█░░░░▄██████████░░░░░░░▄█░░░░▄▀──
───███░░░░███████████░░░░░░▄█░░░░█▀───
────█░░░░░██████████▀░░░░░░█░░░░█▀────
────█░░░░░░▀███████▀░░░░░░░█▄▄▄▀──────
────█░░░░░░░░▀▀▀▀░░░░░░░░░░░▀█────────
────█░░░░░░░░░░░░░░░░░░░░░░░░█────────
────█░░░░░░░░░░░░░░░░░░░░░░░░█────────
────█░░░░░░░░░░░░░░░░░░░░░░░░█────────
──────────────────────────────────────
───█──█─█──█─█──█─█▀▀▀█─█▀▀█─█──█─────
───█▀▀█─█──█─█▄▄█─█───█─█────█──█─────
───█──█─█▄▄█────█─█▄▄▄█─█▄▄█─█▄▄█─────
──────────────────────────────────────
*/
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#include<vector>
#include<set>
#define LL long long
#define db double
#define EPS 1e-15
#define inf 1000000000
#define pa pair<int,int>
#include <iostream>
#include <set>
#define w *v[a].begin()
#define f(b) for(int a=1;a<=b;a++)
#define m 100005
using namespace std;
int n,p,q,x[m],y[m],z[m],o;
set<int> v[m];
void d(int a){
if(z[a]||y[a]||x[a]>2)return;
if(x[a]<2)x[w]++;
else y[w]=1;
v[w].erase(a);
if(v[w].size()==1)d(w);
z[a]=1;
}
int main(){
cin>>n;
f(n-1){
cin>>p>>q;
v[p].insert(q);
v[q].insert(p);
}
f(n)if(v[a].size()==1)d(a);
f(n)if(!z[a]&&v[a].size()>2)o=1;
if(o)cout<<"No";
else cout<<"Yes";
return 0;
}