Codeforces-964D Destruction of a Tree(贪心)
Posted 采蘑菇的小西佬
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces-964D Destruction of a Tree(贪心)相关的知识,希望对你有一定的参考价值。
题意:给你一颗节点数目为n的树,问你能否每次删除一个度为偶数的节点,同时与该节点相连的路也被删除,能否在多次删除操作后删除掉整棵树
题解:从根开始dfs处理出每个节点到根的距离。然后贪心的删除离根最远的偶数度节点。如何证明这个结论是正确的呢?(补题目的时候是多画图然后猜的结论,因为WA了两发后以为是错误的,然后请教了别人,并且证明了这个结论的正确性)因为离根最远的偶数度节点(其子孙一定都是奇数度数的),在将其删除后它所在的那颗树一定被分成两个奇数节点数(注意是节点数!因为只有奇数树才能进行删除操作)的树,从而它的子孙也可以开始删除操作,所以从该点开始删除一定是最优解,如果在当前情况下仍然无法删除所有点,则输出NO。
写的很撮的代码,去看别人的代码,发现他们写的都比我好
#include <iostream> #include <cstdio> #include <cmath> #include <algorithm> #include <map> #include <queue> #include <vector> #include <cstring> #include <iomanip> #include <set> #include<ctime> //CLOCKS_PER_SEC #define se second #define fi first #define ll long long #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define Pii pair<int,int> #define Pli pair<ll,int> #define ull unsigned long long #define pb push_back #define fio ios::sync_with_stdio(false);cin.tie(0) const int N=4e5+5; const ull base=163; const int INF=0x3f3f3f3f; using namespace std; int head[N],nx[N],to[N]; int tot=1; struct node { int le,du,num; friend bool operator < (node a, node b){ if(a.le==b.le) { return a.du>b.du; } return a.le>b.le; } }L[N]; void add(int u,int v){ to[tot]=v; nx[tot]=head[u]; head[u]=tot++; } int dfs(int x,int pre){ for(int i=head[x];i;i=nx[i]){ int v=to[i]; if(v==pre)continue; if(v!=pre)L[x].le+=dfs(v,x); } return L[x].le; } bool vis[N]; vector<int>ans; int main(){ fio; int n; cin>>n; int S=-1; for(int i=1;i<=n;i++){ int x; cin>>x; if(x==0){ S=i; continue; } add(i,x); add(x,i); L[i].du++,L[x].du++; L[i].le=1; L[i].num=i; } if(n%2==0)return cout<<"NO\n",0; L[S].le=1; L[S].num=S; dfs(S,S); priority_queue<node>q; for(int i=1;i<=n;i++){ if(L[i].du%2==0) q.push(L[i]); } while(!q.empty()){ node x=q.top(); q.pop(); if(vis[x.num]||L[x.num].du%2==1)continue; vis[x.num]=1; ans.pb(x.num); for(int i=head[x.num];i;i=nx[i]){ int v=to[i]; if(L[v].du)L[v].du--; if(L[v].du==0&&vis[v]==0){ vis[v]=1; ans.pb(v); } else if(L[v].du%2==0&&!vis[v]){ q.push(L[v]); } } } if(ans.size()==n){ cout<<"YES"<<endl; for(auto i:ans){ cout<<i<<endl; } } else cout<<"NO"<<endl; return 0; }
以上是关于Codeforces-964D Destruction of a Tree(贪心)的主要内容,如果未能解决你的问题,请参考以下文章
C - Splits CodeForces - 964A(规律)