F. Maximum Weight Subset

时光毁灭记忆、已成空白 提交于 2019-12-02 03:20:13

题意:给一颗树,边权为1,节点有点权,问取到一个点集,俩俩之间路径超过k,是点权和最大

思路:贪心地取点,先将点按照深度经行排序,每一次,取一个点权大于0的点,然后对于这个点bfs出去的路径小于k的点减去当前点的a[u],然后将a[i]加入到ans中

#include<bits/stdc++.h>
using namespace std;
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fod(i,a,b) for(int i=b;i>=a;i--)
#define pb push_back
const int M=250;
int deep[M],vis[M],a[M],b[M],k,n;
vector<int>g[M];
void dfs(int u,int f){
    deep[u]=deep[f]+1;
    for(int i=0;i<g[u].size();i++){
        int v=g[u][i];
        if(v!=f){
            dfs(v,u);
        }
    }
}
bool cmp(int x,int y){
    return deep[x]>deep[y];
}
struct node{
    int val,st;
};
int bfs(int st){
    queue<node>que;
    node s;
    s.val=st;
    s.st=0;
    que.push(s);
    memset(vis,0,sizeof(vis));
    int c=a[st];
    while(!que.empty()){
        node u=que.front();
        vis[u.val]=1;
        a[u.val]-=c;
        que.pop();
        if(u.st!=k){
            for(int i=0;i<g[u.val].size();i++){
                int v=g[u.val][i];
                if(!vis[v]){
                    node p;
                    p.val=v;
                    p.st=u.st+1;
                    que.push(p);
                }            
            }
        }
        
    }
    return c;
}
int main(){
    
    scanf("%d%d",&n,&k);
    fo(i,1,n)
        scanf("%d",&a[i]);
    fo(i,1,n-1){
        int x,y;
        scanf("%d%d",&x,&y);
        g[x].pb(y);
        g[y].pb(x);
    }
    dfs(1,0);
    fo(i,1,n)b[i]=i;
    sort(b+1,b+1+n,cmp);
    int ans=0;
    fo(i,1,n)
        if(a[i]>0)
            ans+=bfs(i);
    cout<<ans<<endl;
    return 0;
}
View Code

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!