• BZOJ 2599: [IOI2011]Race(点分治板题)


    我也就只会做做板题了…

    记得清零数组的时候子树遍历清零,否则会T

    CODE

    #include<bits/stdc++.h>
    using namespace std;
    inline void read(int &num) {
    	char ch; int flg = 1; while(!isdigit(ch=getchar()))if(ch=='-')flg = -flg;
    	for(num=0; isdigit(ch); num=num*10+ch-'0', ch=getchar()); num*=flg;
    }
    const int MAXN = 200005;
    const int MAXK = 1000005;
    int n, k, fir[MAXN], cnt;
    struct edge { int to, nxt, w; }e[MAXN<<1];
    inline void link(int u, int v, int ww) {
    	e[++cnt] = (edge){ v, fir[u], ww }, fir[u] = cnt;
    }
    bool ban[MAXN];
    int Get_Size(int x, int ff) {
    	int re = 1;
    	for(int v, i = fir[x]; i; i = e[i].nxt)
    		if(!ban[v=e[i].to] && v != ff) re += Get_Size(v, x);
    	return re;
    }
    int Get_Root(int x, int ff, int Size, int &G) {
    	int re = 1; bool flg = true;
    	for(int v, i = fir[x]; i; i = e[i].nxt)
    		if(!ban[v=e[i].to] && v != ff) {
    			int temp = Get_Root(v, x, Size, G); re += temp;
    			if(temp<<1 > Size) flg = 0;
    		}
    	if(Size-re<<1 > Size) flg = 0;
    	if(flg) G = x;
    	return re;
    }
    int st[MAXN][2], top, Ans;
    void Count(int x, int ff, int dep, int dis) {
    	if(dis > k) return;
    	++top, st[top][0] = dep, st[top][1] = dis;
    	for(int v, i = fir[x]; i; i = e[i].nxt)
    		if(!ban[v=e[i].to] && v != ff)
    			Count(v, x, dep+1, dis+e[i].w);
    }
    int f[MAXK];
    void Clear(int x, int ff, int dis) {
    	if(dis > k) return;
    	f[dis] = n;
    	for(int v, i = fir[x]; i; i = e[i].nxt)
    		if(!ban[v=e[i].to] && v != ff)
    			Clear(v, x, dis+e[i].w);
    }
    inline void Solve(int x) {
    	f[0] = 0;
    	for(int v, i = fir[x]; i; i = e[i].nxt)
    		if(!ban[v=e[i].to]) {
    			Count(v, x, 1, e[i].w);
    			for(int j = 1; j <= top; ++j)
    				Ans = min(Ans, st[j][0] + f[k-st[j][1]]);
    			while(top) f[st[top][1]] = min(f[st[top][1]], st[top][0]), --top;
    		}
    	Clear(x, 0, 0);
    }
    int TDC(int x) {
    	int Size = Get_Size(x, 0);
    	Get_Root(x, 0, Size, x);
    	Solve(x); ban[x] = 1;
    	for(int v, i = fir[x]; i; i = e[i].nxt)
    		if(!ban[v=e[i].to]) TDC(v);
    }
    
    int main() {
    	read(n), read(k); Ans = n;
    	for(int i = 1, x, y, z; i < n; ++i)
    		read(x), read(y), read(z), link(x+1, y+1, z), link(y+1, x+1, z);
    	for(int i = 1; i <= k; ++i) f[i] = n;
    	TDC(1);
    	printf("%d
    ", Ans < n ? Ans : -1);
    }
    
  • 相关阅读:
    ObserverPattern(观察者模式)-----Java/.Net
    MementoPattern(备忘录模式)-----Java/.Net
    SpringCloud-day02-服务消费者项目建立
    SpringCloud-基础项目构建
    idea git 整合使用
    springcloud-知识点总结(三):Hystrix & Dashboard & turbine & Zuul & SpringCloud Config
    springcloud-知识点总结(二):Ribbon&Feign
    springcloud-知识点总结(一):Eureka
    layui-tree创建下拉树型选项框
    ztree带有选项框的树形菜单使用
  • 原文地址:https://www.cnblogs.com/Orz-IE/p/12039290.html
Copyright © 2020-2023  润新知