【luogu1273】 有线电视网 [动态规划 树形dp]

P1273 有线电视网

好早之前就叫做的题了qwq 我太垃圾了现在才跑来把它做了

f[i][j]表示当前节点i 选了j个用户 

其实不用建双向的 因为是一个以1为根节点的树 而且它按顺序输入qwq

#include<bits/stdc++.h>
using namespace std;
#define Max(x,y) (x)>(y)?(x):(y)
#define Min(x,y) (x)>(y)?(y):(x)
#define ll long long
#define rg register
const int N=3000+5,M=10000+5,inf=0x3f3f3f3f,P=99999997;
int n,m,f[N][N],ans,a[N];
bool vis[N];
template <class t>void rd(t &x){
    x=0;int w=0;char ch=0;
    while(!isdigit(ch)) w|=ch=='-',ch=getchar();
    while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
    x=w?-x:x;
}

int head[N<<1],tot=0;
struct edge{int v,w,nxt;}e[N<<1];
void add(int u,int v,int w){
    e[++tot]=(edge){v,w,head[u]},head[u]=tot;
}

int dp(int u){
    vis[u]=1;
    if(u>n-m) {f[u][1]=a[u];return 1;}
    int size=0,vsize;
    for(int i=head[u],v;i;i=e[i].nxt){
        v=e[i].v;
        if(vis[v]) continue;
        vsize=dp(v),size+=vsize;
        for(int k=size;k;--k)
        for(int j=1;j<=vsize;++j)
        if(k-j>=0) f[u][k]=Max(f[u][k],f[u][k-j]+f[v][j]-e[i].w);
    }
    return size;
}

int main(){
    freopen("in.txt","r",stdin);
    rd(n),rd(m);
    for(int i=1,k,v,w;i<=n-m;++i){
        rd(k);
        while(k--) rd(v),rd(w),add(i,v,w),add(v,i,w);
    }
    memset(f,-inf,sizeof(f));
    for(int i=1;i<=m;++i) rd(a[i+n-m]);
    for(int i=1;i<=n;++i) f[i][0]=0;for(int i=m;i;--i)
    if(f[1][i]>=0){ans=i;break;}
    printf("%d",ans);
    return 0;
}
 

 

posted @ 2019-07-18 11:55  委屈的咸鱼鱼鱼鱼  阅读(178)  评论(0编辑  收藏  举报