• bzoj2286: [Sdoi2011消耗战


    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=2286

    思路:构建虚树,treeDP,

    设f[i]表示i的子树所有资源点断开所需代价,dis[i]表示=i到1的路径上的最小边权

    那么如果i是有资源的点,f[i]=dis[i]

    否则f[i]=min(Σf[son[i]],dis[i])

    虚树见上一篇博客:http://http://blog.csdn.net/thy_asdf/article/details/50387136


    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define min(a,b) (a<b?a:b)
    typedef long long ll;
    const int maxn=250010,maxm=500010,maxk=22;
    const ll inf=1ll<<50;
    using namespace std;
    int n,m,fa[maxn][maxk],dep[maxn],cnt,poi[maxn],stk[maxn],top,dfn[maxn],tim;ll f[maxn],dis[maxn];
    bool bo[maxn];
    bool cmp(int a,int b){return dfn[a]<dfn[b];}
    
    struct Tgraph{
    	int pre[maxm],now[maxn],son[maxm],val[maxm],tot;
    	void add(int a,int b,int c){pre[++tot]=now[a],now[a]=tot,son[tot]=b,val[tot]=c;}
    	void add(int a,int b){pre[++tot]=now[a],now[a]=tot,son[tot]=b;}
    	void dfs1(int x){
    		dfn[x]=++tim;
    		for (int i=1;i<=20;i++) fa[x][i]=fa[fa[x][i-1]][i-1];
    		for (int y=now[x];y;y=pre[y]) if (son[y]!=fa[x][0])
    			dep[son[y]]=dep[x]+1,dis[son[y]]=min(dis[x],val[y]),fa[son[y]][0]=x,dfs1(son[y]);
    	}
    	void dfs2(int x){
    		f[x]=dis[x];ll sum=0;
    		for (int y=now[x];y;y=pre[y]) dfs2(son[y]),sum+=f[son[y]];
    		if (sum&&!bo[x]) f[x]=min(f[x],sum);
    		now[x]=0;
    	}
    }g1,g2;
    
    int lca(int a,int b){
    	if (dep[a]<dep[b]) swap(a,b);
    	for (int h=dep[a]-dep[b],i=20;i>=0;i--) if (h>=(1<<i)) h-=(1<<i),a=fa[a][i];
    	if (a==b) return a;
    	for (int i=20;i>=0;i--) if (fa[a][i]!=fa[b][i]) a=fa[a][i],b=fa[b][i];
    	return fa[a][0];
    }
    
    void work(){
    	top=0;
    	for (int i=1;i<=cnt;i++){
    		if (!top){stk[++top]=poi[i];continue;}
    		int u=lca(stk[top],poi[i]);
    		while (dfn[u]<dfn[stk[top]]){
    			if (dfn[u]>=dfn[stk[top-1]]){
    				g2.add(u,stk[top]);
    				if (stk[--top]!=u) stk[++top]=u;
    				break;
    			}
    			g2.add(stk[top-1],stk[top]),top--;
    		}
    		stk[++top]=poi[i];
    	}
    	while (top>1) g2.add(stk[top-1],stk[top]),top--;
    	g2.dfs2(stk[1]),printf("%lld
    ",f[stk[1]]);
    	for (int i=1;i<=cnt;i++) bo[poi[i]]=0;g2.tot=0;
    }
    
    int main(){
    	scanf("%d",&n),dis[1]=inf;
    	for (int i=1,a,b,c;i<n;i++) scanf("%d%d%d",&a,&b,&c),g1.add(a,b,c),g1.add(b,a,c);
    	g1.dfs1(1),scanf("%d",&m);
    	for (int i=1;i<=m;i++){
    		scanf("%d",&cnt);
    		for (int j=1;j<=cnt;j++) scanf("%d",&poi[j]),bo[poi[j]]=1;
    		sort(poi+1,poi+1+cnt,cmp),work();
    	}
    	return 0;
    }
    


  • 相关阅读:
    十个MySQL常用函数
    写给三十岁的自己
    EJS 模板引擎
    发送HTTP请求(GET,POST)
    路由模块化
    原生NodeJS封装Express路由
    Hook简介
    State Hook (useState)
    Effect hooks
    useContext
  • 原文地址:https://www.cnblogs.com/thythy/p/5493492.html
Copyright © 2020-2023  润新知