• 【BZOJ3611】大工程(虚树,动态规划)


    【BZOJ3611】大工程(虚树,动态规划)

    题面

    BZOJ

    Description

    国家有一个大工程,要给一个非常大的交通网络里建一些新的通道。
    我们这个国家位置非常特殊,可以看成是一个单位边权的树,城市位于顶点上。
    在 2 个国家 a,b 之间建一条新通道需要的代价为树上 a,b 的最短路径。
    现在国家有很多个计划,每个计划都是这样,我们选中了 k 个点,然后在它们两两之间 新建 C(k,2)条 新通道。
    现在对于每个计划,我们想知道:
    1.这些新通道的代价和
    2.这些新通道中代价最小的是多少
    3.这些新通道中代价最大的是多少

    Input

    第一行 n 表示点数。
    接下来 n-1 行,每行两个数 a,b 表示 a 和 b 之间有一条边。
    点从 1 开始标号。 接下来一行 q 表示计划数。
    对每个计划有 2 行,第一行 k 表示这个计划选中了几个点。
    第二行用空格隔开的 k 个互不相同的数表示选了哪 k 个点。

    Output

    输出 q 行,每行三个数分别表示代价和,最小代价,最大代价。

    Sample Input

    10

    2 1

    3 2

    4 1

    5 2

    6 4

    7 5

    8 6

    9 7

    10 9

    5

    2

    5 4

    2

    10 4

    2

    5 2

    2

    6 1

    2

    6 1

    Sample Output

    3 3 3

    6 6 6

    1 1 1

    2 2 2

    2 2 2

    HINT

    n<=1000000

    q<=50000并且保证所有k之和<=2*n

    题解

    先考虑正常的(dp)
    对于第一个,总和。设(f[i])表示(i)的子树中的关键点的个数
    转移:(sum+=f[v]*(K-f[v])*len(i,v),f[i]+=f[v])
    对于第二个和第三个,相当于维护树上最长链和最短链
    这个就非常基础了,不写了。

    现在再把这个(dp)放在虚树上做就行了

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<set>
    #include<map>
    #include<vector>
    #include<queue>
    using namespace std;
    #define ll long long
    #define RG register
    #define MAX 1001000
    inline int read()
    {
        RG int x=0,t=1;RG char ch=getchar();
        while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
        if(ch=='-')t=-1,ch=getchar();
        while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
        return x*t;
    }
    struct Line{int v,next,w;}e[MAX<<1];
    int h[MAX],cnt=1;
    inline void Add(int u,int v,int w){e[cnt]=(Line){v,h[u],w};h[u]=cnt++;}
    int n,Q,K;
    int fa[MAX],size[MAX],hson[MAX],dep[MAX],top[MAX],dfn[MAX],low[MAX],tim;
    void dfs1(int u,int ff)
    {
    	fa[u]=ff;dep[u]=dep[ff]+1;size[u]=1;
    	for(int i=h[u];i;i=e[i].next)
    	{
    		int v=e[i].v;if(v==ff)continue;
    		dfs1(v,u);size[u]+=size[v];
    		if(size[v]>size[hson[u]])hson[u]=v;
    	}
    }
    void dfs2(int u,int tp)
    {
    	top[u]=tp;dfn[u]=++tim;
    	if(hson[u])dfs2(hson[u],tp);
    	for(int i=h[u];i;i=e[i].next)
    	{
    		int v=e[i].v;
    		if(v==hson[u]||v==fa[u])continue;
    		dfs2(v,v);
    	}
    	low[u]=tim;
    }
    int LCA(int u,int v)
    {
    	while(top[u]^top[v])(dep[top[u]]<dep[top[v]])?v=fa[top[v]]:u=fa[top[u]];
    	return dep[u]<dep[v]?u:v;
    }
    int S[MAX],p[MAX<<1];
    bool vis[MAX];
    bool cmp(int u,int v){return dfn[u]<dfn[v];}
    int Min,Max,KK;
    ll Sum;
    int f1[MAX],f2[MAX],f3[MAX];
    void DP(int u)
    {
    	if(vis[u])f1[u]=1,f2[u]=0,f3[u]=0;
    	else f1[u]=0,f2[u]=1e9,f3[u]=-1e9;
    	for(int i=h[u];i;i=e[i].next)
    	{
    		int v=e[i].v;DP(v);
    		Sum+=1ll*f1[v]*(KK-f1[v])*e[i].w;f1[u]+=f1[v];
    		Min=min(Min,f2[u]+f2[v]+e[i].w);f2[u]=min(f2[u],f2[v]+e[i].w);
    		Max=max(Max,f3[u]+f3[v]+e[i].w);f3[u]=max(f3[u],f3[v]+e[i].w);
    	}
    }
    int main()
    {
    	n=read();
    	for(int i=1;i<n;++i)
    	{
    		int u=read(),v=read();
    		Add(u,v,0);Add(v,u,0);
    	}
    	dfs1(1,0);dfs2(1,1);
    	memset(h,0,sizeof(h));
    	Q=read();
    	while(Q--)
    	{
    		K=KK=read();cnt=1;int tp=0;
    		for(int i=1;i<=K;++i)vis[p[i]=read()]=true;
    		sort(&p[1],&p[K+1],cmp);
    		for(int i=K;i>1;--i)p[++K]=LCA(p[i],p[i-1]);
    		sort(&p[1],&p[K+1],cmp);K=unique(&p[1],&p[K+1])-p-1;
    		for(int i=1;i<=K;++i)
    		{
    			while(tp&&low[S[tp]]<dfn[p[i]])--tp;
    			Add(S[tp],p[i],dep[p[i]]-dep[S[tp]]);
    			S[++tp]=p[i];
    		}
    		Sum=0;Min=1e9;Max=-1e9;DP(p[1]);
    		printf("%lld %d %d
    ",Sum,Min,Max);
    		for(int i=1;i<=K;++i)vis[p[i]]=false,h[p[i]]=0;
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    乐视电视修改五大图标
    Google Home Mini配置失败解决办法
    使用FreeHttp任意篡改http报文 (FreeHttp使用及实现说明)
    IDEA和VS快捷键对比
    C# 中的字符串内插
    在线运行.NET代码
    在Windows服务器安装ss服务端用于逃脱公司行为管理
    .NET Core的代码安全分析工具
    用DotNetDetour HOOK .net类库
    C#代码获取另一程序的错误提示,并关闭窗口。
  • 原文地址:https://www.cnblogs.com/cjyyb/p/9067086.html
Copyright © 2020-2023  润新知