• 【BZOJ1758】【WC2010】重建计划(点分治,单调队列)


    【BZOJ1758】【WC2010】重建计划(点分治,单调队列)

    题面

    BZOJ
    洛谷

    Description

    img

    Input

    第一行包含一个正整数N,表示X国的城市个数. 第二行包含两个正整数L和U,表示政策要求的第一期重建方案中修建道路数的上下限 接下来的N-1行描述重建小组的原有方案,每行三个正整数Ai,Bi,Vi分别表示道路(Ai,Bi),其价值为Vi 其中城市由1..N进行标号

    Output

    输出最大平均估值,保留三位小数

    Sample Input

    4
    2 3
    1 2 1
    1 3 2
    1 4 3

    Sample Output

    2.500

    HINT

    N<=100000,1<=L<=U<=N-1,Vi<=1000000

    题解

    我这鬼代码在BZOJ上跑不过去
    因为(BZOJ)添加了一组很鬼畜的数据,导致(BZOJ)上会(TLE)
    洛谷上能过。

    表示完全不会点分治了,这道题目就当复习用。

    每次我们二分一个答案,将所有的边权全部减去这个二分的值
    此时题目相当于询问是否存在一条边数在([L,U])之间,权值和大于(0)的路径。
    考虑每个分治重心的贡献,依次计算当前重心的每一棵子树,
    求出所有点的深度(经过的边数),以及权值和
    对于每个深度,维护一个前面所有子树的最大权值和。
    为了方便计算,按照所有点按照深度排序,这样就用(bfs)便利子树就行了。
    开始考虑前面的所有子树与当前子树的贡献
    用一个指针从大到小维护所有可以的前面子树中的链
    同时用单调队列维护一下单调性
    每次取出满足经过的边数在([L,U])之间,并且权值和最大的边出来进行组合,计算一下是否满足二分的答案就好了。。

    #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 111111
    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;
    }
    int n,L,U;
    double ans;
    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 size[MAX],Size,root,mx,MD;
    bool vis[MAX];
    double t[MAX],dis[MAX];
    void Getroot(int u,int ff)
    {
    	size[u]=1;int ret=1;
    	for(int i=h[u];i;i=e[i].next)
    	{
    		int v=e[i].v;if(vis[v]||v==ff)continue;
    		Getroot(v,u);size[u]+=size[v];
    		ret=max(ret,size[v]);
    	}
    	ret=max(ret,Size-size[u]);
    	if(mx>ret)mx=ret,root=u;
    }
    int Q[MAX],H,T,Vis[MAX],dep[MAX];
    void bfs(int u,double d)
    {
    	Q[H=T=1]=u;Vis[u]=true;
    	while(H<=T)
    	{
    		int u=Q[H++];
    		for(int i=h[u];i;i=e[i].next)
    		{
    			int v=e[i].v;if(vis[v]||Vis[v])continue;
    			dep[v]=dep[u]+1;dis[v]=dis[u]+e[i].w-d;
    			Q[++T]=v;Vis[v]=true;
    		}
    	}
    }
    int q[MAX];
    bool check(int u,double d)
    {
    	bool fl=false;int md=0;
    	for(int ee=h[u];ee&&!fl;ee=e[ee].next)
    	{
    		int v=e[ee].v;if(vis[v])continue;
    		dis[v]=e[ee].w-d;dep[v]=1;
    		bfs(v,d);
    		int hh=1,tt=0,j=md;
    		for(int i=1;i<=T;++i)
    		{
    			while(j>=0&&j+dep[Q[i]]>=L)
    			{
    				while(hh<=tt&&t[q[tt]]<t[j])--tt;
    				q[++tt]=j;--j;
    			}
    			while(hh<=tt&&dep[Q[i]]+q[hh]>U)++hh;
    			if(hh<=tt&&dis[Q[i]]+t[q[hh]]>=0)fl=true;
    		}
    		md=max(md,dep[Q[T]]);
    		for(int i=1;i<=T;++i)
    		{
    			Vis[Q[i]]=false;
    			t[dep[Q[i]]]=max(t[dep[Q[i]]],dis[Q[i]]);
    		}
    	}
    	for(int i=1;i<=md;++i)t[i]=-1e12;
    	return fl;
    }
    void Calc(int u)
    {
    	double l=ans,r=MD;
    	while(r-l>1e-4)
    	{
    		double mid=(l+r)/2;
    		if(check(u,mid))l=mid;
    		else r=mid;
    	}
    	ans=l;
    }
    void DFS(int u)
    {
    	vis[u]=true;Calc(u);
    	for(int i=h[u];i;i=e[i].next)
    	{
    		int v=e[i].v;if(vis[v])continue;
    		Size=size[v];mx=n;Getroot(v,0);
    		DFS(root);
    	}
    }
    int main()
    {
    	n=read();L=read();U=read();
    	for(int i=1;i<n;++i)
    	{
    		int u=read(),v=read(),w=read();
    		Add(u,v,w);Add(v,u,w);MD=max(MD,w);
    	}
    	Size=mx=n;Getroot(1,0);
    	DFS(root);
    	printf("%.3lf
    ",ans);
    	return 0;
    }
    
    
  • 相关阅读:
    Delphi中的进制转换
    delphi inttohex 整型到十六进制
    delphi将程序最小化至右下角
    sql server 本地复制订阅 实现数据库服务器 读写分离
    我在DBGridEh增加一栏复选框及对应操作的解决方案
    Application.CreateForm()和TForm.Create()创建的窗体有什么区别么?二者在使用上各有什么技巧?(50分)
    学用 TStringGrid [6]
    SQL Server中一些有用的日期sql语句
    MVC中的@Html.DisplayFor等方法如何控制日期的显示格式(转)
    ASP.NET MVC自定义AuthorizeAttribute篇知识点讲解—登录限制
  • 原文地址:https://www.cnblogs.com/cjyyb/p/8820414.html
Copyright © 2020-2023  润新知