• P4149 [IOI2011]Race dsu on tree


    这题据说是点分治,但是看到有大佬说dus on tree可以写出来,就试了试。。。

    https://www.luogu.com.cn/problem/P4149

    这个题让我再一次认识了树上启发式合并,谢谢,具体看代码就好

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<map>
    #include<vector>
    using namespace std;
    const int maxn = 2e5 + 1010;
    typedef long long ll;
    int k;
    map<ll,ll>ins;
    int n;
    
    struct Node {
    	int p;
    	ll len;
    	Node(int _p,ll _len):p(_p),len(_len) {}
    };
    
    
    
    vector<Node>G[maxn];
    void add(int be, int en,ll len) {
    	G[be].push_back(Node(en,len));
    }
    
    
    int siz[maxn];
    int son[maxn];
    ll dep[maxn];
    ll dis[maxn];
    
    int dfs(int x, int fa,ll d,ll dd) {
    	siz[x] = 1;
    	dis[x] = dd;
    	dep[x] = d;
    	
    	int c = 0;
    	for (int i=0; i<G[x].size(); i++) {
    		int p = G[x][i].p;
    		ll len = G[x][i].len;
    		if (p == fa) continue;
    		dfs(p, x,d+1,dd+len);
    
    		siz[x] += siz[p];
    		if (siz[p] > c) {
    			c = siz[p];
    			son[x] = p;
    		}
    	}
    	return 0;
    }
    ll cns = 0;
    ll ans;
    
    
    int cal(int root,int x, int fa) {
    	
    
    	ll ln = k+2*dis[root] - dis[x];
    	
    	if(ins[ln]) {
    		ans = min(ans,dep[x] + ins[ln] - 2LL*dep[root]);
    	}
    	
    	for (int i=0; i<G[x].size(); i++) {
    		int p = G[x][i].p;
    		ll len = G[x][i].len;
    		if (p == fa) continue;
    		cal(root,p, x);
    	}
    	return 0;
    }
    int cal2(int x, int fa) {
    	if(ins[dis[x]] == 0){
    		ins[dis[x]] = dep[x];
    	} 
    	else{
    		ins[dis[x]] = min(ins[dis[x]],dep[x]);
    	}
    	if(dis[x] == k) {
    		ans = min(ans,dep[x]-1);
    	}
    	
    	for (int i=0; i<G[x].size(); i++) {
    		int p = G[x][i].p;
    		ll len = G[x][i].len;
    		if (p == fa) continue;
    		cal2(p, x);
    	}
    	return 0;
    }
    
    int dfs2(int x, int fa, int flag) {
    	for (int i=0; i<G[x].size(); i++) { //先算轻儿子
    		int p = G[x][i].p;
    		ll len = G[x][i].len;
    		if (p == fa) continue;
    		if (p == son[x]) continue;
    		dfs2(p, x, 0);
    	}
    
    	if (son[x] != 0) {//单独算重儿子
    		dfs2(son[x], x, 1);
    	}
    	
    	
    	
    	ll ln = k+dis[x] ;
    	
    	if(ins[ln]) {
    		ans = min(ans,dep[x] + ins[ln] - 2LL*dep[x]);
    	}
    	
    	if(ins[dis[x]] == 0) ins[dis[x]] = dep[x];
    	
    	for(int i=0;i<G[x].size();i++){
    		int p = G[x][i].p;
    		if(p == fa || p == son[x]) continue;
    		cal(x,p,x);
    		cal2(p,x);
    	}
    	
    	if (flag == 0) {//删除答案
    		ins.clear();
    	}
    	return 0;
    }
    
    
    
    int main() {
    ////
    //	freopen("in.txt", "r", stdin);
    //	freopen("out.txt", "w", stdout);
    
    	int be;
    	scanf("%d %d", &n,&k);
    	int x,y;
    	ll len;
    	ans = 1e17;
    	for (int i = 2; i <= n; i++) {
    		scanf("%d %d %lld",&x,&y,&len);
    		x++,y++;
    		add(x,y,len);
    		add(y,x,len);
    	}
    	dfs(1, -1,1,0);
    	dfs2(1, -1, 0);
    
    	if(ans == 1e17) ans = -1;
    
    	printf("%lld
    ",ans);
    
    	return 0;
    }
    

      

    寻找真正的热爱
  • 相关阅读:
    python装饰器的简单理解
    自动化测试接口大纲
    web测试方法小结----以便于测试用例
    git 路上的拦路虎 了解一下
    python+selenium +unittest生成HTML测试报告
    Ext.js 初识
    Ajax
    JIRA使用
    win10系统注册表基础知识
    Markdown 模式下 代码的折叠与展开
  • 原文地址:https://www.cnblogs.com/lesning/p/13786069.html
Copyright © 2020-2023  润新知