• 【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
    ",ans);
    118     return 0;
    119 }
  • 相关阅读:
    到现在为止中国荣获43金
    php fpdf 生成表格总结
    今天,开心``
    js 浮动层实现方法
    奥运,刘翔,CSDN,菲尔普斯,中国
    marc 数据基本字段
    Windows mobile下获取系统图标
    HTTP协议学习笔记
    UNIX网络编程学习(14)使用select正确处理EOF的str_cli函数修订版
    ARP协议学习笔记
  • 原文地址:https://www.cnblogs.com/myx12345/p/11728950.html
Copyright © 2020-2023  润新知