【CF1249F】Maximum Weight Subset(贪心)

题意:给定一棵n个点带点权的树,要求从中选出一个点集,使得这些点两两之间距离都大于K,求最大点权和

n,K<=2e2,1<=a[i]<=1e5

思路:树形DP显然可做,极限是n方,然而贪心也是,还比dp好写

可以用寒假camp里cls差不多的想法

从深度大的向上贪心,暴力维护对答案的贡献,即如果贡献大于0就取,并将距当前点距离<=K的贡献减去当前点

评论区甚至有红名大佬做到了线性复杂度

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 typedef long long ll;
  4 typedef unsigned int uint;
  5 typedef unsigned long long ull;
  6 typedef pair<int,int> PII;
  7 typedef pair<ll,ll> Pll;
  8 typedef vector<int> VI;
  9 typedef vector<PII> VII;
 10 //typedef pair<ll,ll>P;
 11 #define N  300010
 12 #define M  2000010
 13 #define fi first
 14 #define se second
 15 #define MP make_pair
 16 #define pb push_back
 17 #define pi acos(-1)
 18 #define mem(a,b) memset(a,b,sizeof(a))
 19 #define rep(i,a,b) for(int i=(int)a;i<=(int)b;i++)
 20 #define per(i,a,b) for(int i=(int)a;i>=(int)b;i--)
 21 #define lowbit(x) x&(-x)
 22 #define Rand (rand()*(1<<16)+rand())
 23 #define id(x) ((x)<=B?(x):m-n/(x)+1)
 24 #define ls p<<1
 25 #define rs p<<1|1
 26 
 27 const ll MOD=1e9+7,inv2=(MOD+1)/2;
 28       double eps=1e-6;
 29       int INF=1e9;
 30       int dx[4]={-1,1,0,0};
 31       int dy[4]={0,0,-1,1};
 32 
 33       int head[N],nxt[N],vet[N],a[N],b[N],d[N],dis[N],q[N],tot,n,K;
 34 
 35 int read()
 36 {
 37    int v=0,f=1;
 38    char c=getchar();
 39    while(c<48||57<c) {if(c=='-') f=-1; c=getchar();}
 40    while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar();
 41    return v*f;
 42 }
 43 
 44 void add(int a,int b)
 45 {
 46     nxt[++tot]=head[a];
 47     vet[tot]=b;
 48     head[a]=tot;
 49 }
 50 
 51 void dfs(int u,int fa)
 52 {
 53     int e=head[u];
 54     while(e)
 55     {
 56         int v=vet[e];
 57         if(v!=fa)
 58         {
 59             d[v]=d[u]+1;
 60             dfs(v,u);
 61         }
 62         e=nxt[e];
 63     }
 64 }
 65 
 66 bool cmp(int a,int b)
 67 {
 68     return d[a]>d[b];
 69 }
 70 
 71 int calc(int st)
 72 {
 73     rep(i,1,n) dis[i]=-1;
 74     dis[st]=0;
 75     int t=0,w=1;
 76     q[1]=st;
 77     int res=a[st];
 78     while(t<w)
 79     {
 80         t++;
 81         int u=q[t];
 82         a[u]-=res;
 83         if(dis[u]==K) continue;
 84         int e=head[u];
 85         while(e)
 86         {
 87             int v=vet[e];
 88             if(dis[v]==-1)
 89             {
 90                 w++; q[w]=v; dis[v]=dis[u]+1;
 91             }
 92             e=nxt[e];
 93         }
 94 
 95     }
 96     return res;
 97 }
 98 
 99 int main()
100 {
101     n=read(),K=read();
102     rep(i,1,n) a[i]=read();
103     rep(i,1,n) head[i]=0;
104     tot=0;
105     rep(i,1,n-1)
106     {
107         int x=read(),y=read();
108         add(x,y);
109         add(y,x);
110     }
111     dfs(1,0);
112     rep(i,1,n) b[i]=i;
113     sort(b+1,b+n+1,cmp);
114     int ans=0;
115     rep(i,1,n)
116      if(a[b[i]]>0) ans+=calc(b[i]);
117     printf("%d\n",ans);
118     return 0;
119 }

 

posted on 2019-10-23 21:11  myx12345  阅读(251)  评论(0编辑  收藏  举报

导航