zoukankan      html  css  js  c++  java
  • Bzoj1758: [Wc2010]重建计划

    题面

    传送门

    Sol

    题意就是给你一棵树,有边权
    求边数在([L, U])内的一条路径,使得边权和除以边数最大,输出这个最大值


    二分答案+点分治+单调队列
    二分一个答案(mid),把所有的边权减去这个(mid)就是(check)是否有一条边数满足要求的大于等于零的路径
    (bfs)求出当前每个点到根的(dis)(deep),使其递增
    记录下每个深度最大的(dis),维护这个的递减的单调队列即可

    注意常数优化!!!

    奉上加了一组数据后的(TLE)代码供参考加什么数据咯
    然后博主不想改

    # include <bits/stdc++.h>
    # define RG register
    # define IL inline
    # define Fill(a, b) memset(a, b, sizeof(a))
    using namespace std;
    typedef long long ll;
    const int _(1e5 + 5);
    const double EPS(1e-4);
    
    IL int Input(){
        RG int x = 0, z = 1; RG char c = getchar();
        for(; c < '0' || c > '9'; c = getchar()) z = c == '-' ? -1 : 1;
        for(; c >= '0' && c <= '9'; c = getchar()) x = (x << 1) + (x << 3) + (c ^ 48);
        return x * z;
    }
    
    int n, L, U, first[_], cnt, mx[_], root, size[_], vis[_], tot;
    int mark[_], tmp, deep[_];
    double ans, dis[_], t[_];
    struct Edge{
        int to, w, next;
    } edge[_ << 1];
    int head, tail, Q[_], deq[_];
    
    IL void Add(RG int u, RG int v, RG int w){
        edge[cnt] = (Edge){v, w, first[u]}, first[u] = cnt++;
    }
    
    IL void GetRoot(RG int u, RG int ff){
        size[u] = 1, mx[u] = 0;
        for(RG int e = first[u]; e != -1; e = edge[e].next){
            RG int v = edge[e].to;
            if(vis[v] || v == ff) continue;
            GetRoot(v, u);
            size[u] += size[v];
            mx[u] = max(mx[u], size[v]);
        }
        mx[u] = max(mx[u], tot - size[u]);
        if(mx[u] < mx[root]) root = u;
    }
    
    IL void Bfs(RG double mid, RG int x){
    	Q[head = tail = 0] = x, mark[x] = 1;
    	while(head <= tail){
    		RG int u = Q[head++];
    		for(RG int e = first[u]; e != -1; e = edge[e].next){
    			RG int v = edge[e].to, w = edge[e].w;
    			if(vis[v] || mark[v]) continue;
    			deep[v] = deep[u] + 1, dis[v] = dis[u] + (double)w - mid;
    			Q[++tail] = v, mark[v] = 1;
    		}
    	}
    }
    
    IL bool Check(RG double mid, RG int u){
    	RG int maxd = 0, flg = 0; t[0] = 0; 
    	for(RG int e = first[u]; e != -1; e = edge[e].next){
    		RG int v = edge[e].to, w = edge[e].w;
    		if(vis[v]) continue;
    		dis[v] = (double)w - mid, deep[v] = 1;
    		Bfs(mid, v);
    		for(RG int i = 0; i <= tail; ++i) mark[Q[i]] = 0;
    		RG int he = 0, ta = -1, j = maxd;
    		for(RG int i = 0; i <= tail; ++i){
    			RG int x = Q[i];
    			while(~j && j + deep[x] >= L){
    				while(he <= ta && t[deq[ta]] < t[j]) --ta;
    				deq[++ta] = j--;
    			}
    			while(he <= ta && deep[x] + deq[he] > U) ++he;
    			if(he <= ta && dis[x] + t[deq[he]] >= 0){
    				flg = 1;
    				break;
    			}
    		}
    		maxd = max(maxd, deep[Q[tail]]);
    		if(flg) break;
    		for(RG int i = 0; i <= tail; ++i){
    			RG int x = Q[i];
    			t[deep[x]] = max(t[deep[x]], dis[x]);
    		}
    	}
    	for(RG int i = 0; i <= maxd; ++i) t[i] = -1e12;
    	return flg;
    }
    
    IL void Calc(RG int u){
    	RG double l = ans, r = tmp;
    	while(r - l > EPS){
    		RG double mid = (l + r) / 2;
    		if(Check(mid, u)) l = mid;
    		else r = mid;
    	}
    	ans = l;
    }
    
    IL void Solve(RG int u){
        vis[u] = 1, Calc(u);
        for(RG int e = first[u]; e != -1; e = edge[e].next){
            RG int v = edge[e].to;
            if(vis[v]) continue;
            root = 0, tot = size[v];
    		if(tot <= L) continue;
            GetRoot(v, u), Solve(root);
        }
    }
    
    int main(RG int argc, RG char* argv[]){
        tot = n = Input(), L = Input(), U = Input();
    	for(RG int i = 0; i <= n; ++i) first[i] = -1, t[i] = -1e12;
        for(RG int i = 1; i < n; ++i){
            RG int u = Input(), v = Input(), w = Input();
            Add(u, v, w), Add(v, u, w), tmp = max(tmp, w);
        }
    	mx[0] = n + 1, GetRoot(1, 0), Solve(root);
        printf("%.3lf
    ", ans);
        return 0;
    }
    
    
  • 相关阅读:
    天生我牛必有用
    struts1.x+spring2.5+JPA(hibernate)整合
    Struts2拦截器
    使用Apache的commonscodes加密
    解放鞋 Ospop解放鞋
    告别2008 明天2009
    异常java.lang.UnsupportedClassVersionError: Bad version number in .class file
    C#中的Process类使用
    C#中使用MD5加密
    Struts2 Action(1)
  • 原文地址:https://www.cnblogs.com/cjoieryl/p/8470800.html
Copyright © 2011-2022 走看看