rt,我写的就是现贪心选尽量大的子树然后再构造方案,通过代码如下:
#include<bits/stdc++.h>
#define ll long long
#define N 500005
using namespace std;
ll read(){
ll x=0,f=1;char ch=getchar();
while(ch<'0' || ch>'9')f=(ch=='-'?-1:f),ch=getchar();
while(ch>='0' && ch<='9')x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
return x*f;
}
void write(ll x){
if(x<0)x=-x,putchar('-');
if(x/10)write(x/10);
putchar(x%10+'0');
}
vector<ll> e[N];
ll siz[N];
struct Node{
ll val,num;
Node(ll val=0,ll num=0):val(val),num(num){}
}a[N];
bool cmp(Node x,Node y){
return x.val>y.val;
}
void dfs(ll x,ll fa){
siz[x]=1;
for(auto v:e[x])if(v!=fa)dfs(v,x),siz[x]+=siz[v];
}
ll act[N],cnt,tot;
void dfs2(ll x,ll fa){
if(act[x])act[x]=++cnt;
for(auto v:e[x])if(v!=fa)dfs2(v,x);
if(!act[x])act[x]=++tot;
}
int main(){
#ifdef EAST_CLOUD
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
#endif
ll n=read(),k=read();
for(ll i=1;i<n;i++){
ll u=read(),v=read();
e[u].push_back(v);e[v].push_back(u);
}
dfs(1,0);ll sum=0;
for(ll i=1;i<=n;i++)sum+=siz[i],a[i]=Node(siz[i],i);
if(k>sum || k<n){printf("No\n");return 0;}
sort(a+1,a+n+1,cmp);
for(ll i=1;i<=n;i++){
if(k>=a[i].val)k-=a[i].val,cnt++,act[a[i].num]=1;
}
cnt=n-cnt;
dfs2(1,0);printf("Yes\n");
for(ll i=1;i<=n;i++)write(act[i]),putchar(' ');
return 0;
}
而我一开始将其中的 dfs2 函数写成了
void dfs2(ll x,ll fa){
if(act[x])act[x]=++cnt;
if(!act[x])act[x]=++tot;
for(auto v:e[x])if(v!=fa)dfs2(v,x);
}
即将对没被选择的点按上升顺序标号,但是我觉得这应该没有问题,因为根节点必然被选择且标号比所有没被选择的点标号都大,因此无论顺序怎样必然不影响答案,但是这份代码却 WA 了,想问下是为什么。
WA 完整代码:
#include<bits/stdc++.h>
#define ll long long
#define N 500005
using namespace std;
ll read(){
ll x=0,f=1;char ch=getchar();
while(ch<'0' || ch>'9')f=(ch=='-'?-1:f),ch=getchar();
while(ch>='0' && ch<='9')x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
return x*f;
}
void write(ll x){
if(x<0)x=-x,putchar('-');
if(x/10)write(x/10);
putchar(x%10+'0');
}
vector<ll> e[N];
ll siz[N];
struct Node{
ll val,num;
Node(ll val=0,ll num=0):val(val),num(num){}
}a[N];
bool cmp(Node x,Node y){
return x.val>y.val;
}
void dfs(ll x,ll fa){
siz[x]=1;
for(auto v:e[x])if(v!=fa)dfs(v,x),siz[x]+=siz[v];
}
ll act[N],cnt,tot;
void dfs2(ll x,ll fa){
if(act[x])act[x]=++cnt;
else act[x]=++tot;
for(auto v:e[x])if(v!=fa)dfs2(v,x);
}
int main(){
#ifdef EAST_CLOUD
freopen("a.in","r",stdin);
freopen("a.out","w",stdout);
#endif
ll n=read(),k=read();
for(ll i=1;i<n;i++){
ll u=read(),v=read();
e[u].push_back(v);e[v].push_back(u);
}
dfs(1,0);ll sum=0;
for(ll i=1;i<=n;i++)sum+=siz[i],a[i]=Node(siz[i],i);
if(k>sum || k<n){printf("No\n");return 0;}
sort(a+1,a+n+1,cmp);
for(ll i=1;i<=n;i++){
if(k>=a[i].val)k-=a[i].val,cnt++,act[a[i].num]=1;
}
cnt=n-cnt;
dfs2(1,0);printf("Yes\n");
for(ll i=1;i<=n;i++)write(act[i]),putchar(' ');
return 0;
}