• 【BZOJ3935】—RBTree(树形dp)


    传送门


    把距离的限制列出来好像可以单纯形做


    考虑f[i][j][k]f[i][j][k]表示ii的子树中有jj个黑点,最近的点为kk的最小代价(k不一定在ii子树内)

    考虑转移边uvu ightarrow v的时候,如果u,vu,vkk一样就可以直接转移
    否则是uu的在外面vv的在子树内,取vv子树内最小值即可
    u,vu,v的都在外面而且不一样的话显然是没用的状态
    因为这时候u,vu,v最近的点一定相同

    记一下sizsiz可以做到O(n3)O(n^3)
    喜提bzoj rkbzoj rk倒数第一

    #include<bits/stdc++.h>
    using namespace std;
    const int RLEN=1<<20|1;
    inline char gc(){
        static char ibuf[RLEN],*ib,*ob;
        (ob==ib)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
        return (ob==ib)?EOF:*ib++;
    }
    #define gc getchar
    inline int read(){
        char ch=gc();
        int res=0,f=1;
        while(!isdigit(ch))f^=ch=='-',ch=gc();
        while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
        return f?res:-res;
    }
    #define ll long long
    #define re register
    #define pii pair<int,int>
    #define fi first
    #define se second
    #define pb push_back
    #define cs const
    #define bg begin
    inline void chemx(int &a,int b){a<b?a=b:0;}
    inline void chemn(int &a,int b){a>b?a=b:0;}
    cs int N=505;
    ll dis[N][N],*dep;
    int in[N],out[N],idx[N],dfn,inf,tot,siz[N];
    int adj[N],nxt[N<<1],to[N<<1],val[N<<1],cnt;
    int n,f[N][N][N],g[N][N],c[N],mxdis;
    inline void addedge(int u,int v,int w){
    	nxt[++cnt]=adj[u],adj[u]=cnt,to[cnt]=v,val[cnt]=w;
    }
    void dfs(int u,int fa){
    	for(int e=adj[u];e;e=nxt[e]){
    		int v=to[e];
    		if(v==fa)continue;
    		dep[v]=dep[u]+val[e],dfs(v,u);
    	}
    }
    void dfs2(int u,int fa){
    	in[u]=++dfn,idx[dfn]=u;
    	for(int e=adj[u];e;e=nxt[e]){
    		int v=to[e];
    		if(v==fa)continue;
    		dfs2(v,u);
    	}
    	out[u]=dfn;
    }
    void dp(int u,int fa){
    	siz[u]=1;
    	if(c[u])f[u][1][u]=0;
    	else f[u][1][u]=1;
    	for(int i=1;i<=n;i++)if(i!=u&&dis[i][u]<=mxdis)f[u][0][i]=0;
    	for(int e=adj[u];e;e=nxt[e]){
    		int v=to[e];
    		if(v==fa)continue;
    		dp(v,u);
    		memset(g,127/3,sizeof(g));
    		for(int x=0;x<=siz[u];x++)
    		for(int y=0;y<=siz[v];y++){
    			for(int k=1;k<=n;k++)chemn(g[x+y][k],f[u][x][k]+f[v][y][k]);
    			int res=inf;
    			for(int k=in[v];k<=out[v];k++)chemn(res,f[v][y][idx[k]]);
    			for(int k=1;k<in[v];k++)chemn(g[x+y][idx[k]],f[u][x][idx[k]]+res);
    			for(int k=out[v]+1;k<=n;k++)chemn(g[x+y][idx[k]],f[u][x][idx[k]]+res);
    		}
    		siz[u]+=siz[v],memcpy(f[u],g,sizeof(g));
    	}
    }
    int main(){
    	n=read(),mxdis=read();
    	for(int i=1;i<=n;i++)c[i]=read(),tot+=c[i]==1;
    	for(int i=1;i<n;i++){
    		int u=read(),v=read(),w=read();
    		addedge(u,v,w),addedge(v,u,w);
    	}
    	for(int i=1;i<=n;i++)dep=dis[i],dfs(i,0);
    	memset(f,127/3,sizeof(f));inf=f[0][0][0];
    	dfs2(1,0);
    	dp(1,0);
    	int res=inf;
    	for(int i=1;i<=n;i++)chemn(res,f[1][tot][i]);
    	if(res==inf)cout<<-1;
    	else cout<<res;
    }
    
  • 相关阅读:
    WebStorm 9 配置 Live Edit 功能与浏览器实现同步
    开源JS图片裁剪插件
    cropper手机使用实例
    Laravel中的Storage::disk
    laravel删除文件
    cropper.js移动端使用
    资本的一些运作规律及启示
    laravel文件存储、删除、移动等操作
    解决div和父div不上对齐
    ubuntu14.04如何卸载qq
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/12328582.html
Copyright © 2020-2023  润新知