zoukankan      html  css  js  c++  java
  • [IOI2011]Race(树上启发式合并)

    题意:

    给一棵树,每条边有权,求一条简单路径,使得权值和等于k且边权最小。

    题解:

    DSU on Tree裸题,合并的时候套个map就行。注意慎用Splay,Splay常数巨大,并且感觉好像复杂度并不是均摊的。

    
    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=2e6+100;
    typedef long long ll;
    map<ll,int> mp;
    vector<pair<int,int> > g[maxn];
    int n,m;
    int L[maxn],R[maxn],son[maxn],tol;
    ll dep[maxn];
    int ans=1e9,h[maxn],id[maxn];
    void dfs1 (int u,int f) {
    	L[u]=++tol;
    	id[tol]=u;
    	for (pair<int,int> it:g[u]) {
    		int v=it.first;
    		if (v==f) continue;
    		dep[v]=dep[u]+it.second;
    		h[v]=h[u]+1;
    		dfs1(v,u);
    		if (!son[u]) son[u]=v;
    		else if (R[v]-L[v]+1>R[son[u]]-L[son[u]]+1) son[u]=v;
    	}
    	R[u]=tol;
    }
    void cal (int u,int f) {
    	if (mp.count(dep[u]+m))ans=min(ans,mp[dep[u]+m]-h[u]);
    	if (!mp.count(dep[u]))mp[dep[u]]=h[u];
    	else mp[dep[u]]=min(mp[dep[u]],h[u]);
    	//splay内存储重儿子的所有节点路径 
    	for (pair<int,int> it:g[u]) {
    		int v=it.first;
    		if (v==son[u]) {
    			continue;
    		} 
    		if (v==f) continue;
    		for (int j=L[v];j<=R[v];j++) {
    			if (mp.count(1ll*m+2ll*dep[u]-dep[id[j]]))ans=min(ans,mp[1ll*m+2ll*dep[u]-dep[id[j]]]+h[id[j]]-2*h[u]);
    		}
    		for (int j=L[v];j<=R[v];j++) {
    			//ins(dep[id[j]],h[id[j]]);
    			if (!mp.count(dep[id[j]]))mp[dep[id[j]]]=h[id[j]];
    			else mp[dep[id[j]]]=min(mp[dep[id[j]]],h[id[j]]);
    		}
    	}
    }
    void dfs (int u,int f,int kp) {
    	for (pair<int,int> it:g[u]) {
    		int v=it.first;
    		if (v==f) continue;
    		if (v==son[u]) continue;
    		dfs(v,u,0);
    	}
    	if (son[u]) dfs(son[u],u,1);
    	cal(u,f);
    	if (!kp) mp.clear();
    }
    int main () {
    	scanf("%d%d",&n,&m);
    	for (int i=1;i<n;i++) {
    		int u,v,w;
    		scanf("%d%d%d",&u,&v,&w);
    		u++;v++;
    		g[u].push_back(make_pair(v,w));
    		g[v].push_back(make_pair(u,w));
    	}
    
    	dfs1(1,0);
    	dfs(1,0,1);
    	if (ans>n) ans=-1;
    	printf("%d
    ",ans);
    }
  • 相关阅读:
    关于下下载typora的相关说明
    Vue项目vscode 安装eslint插件的方法(代码自动修复)
    [0].Net开发者社区--您好大的官威啊!
    关于hadoop安装后无法访问web界面查看查看 NameNode 和 Datanode 信息
    C#(winform)记录阻止关闭页面方法
    Android开发:记录Cannot resolve symbol'R'问题解决记录
    C#Winform开发杂项记录
    C#Winform 使用NPOI导入、导出Excel
    C#记录一些用到的比对方法
    C#(Winform开发)Excel导出
  • 原文地址:https://www.cnblogs.com/zhanglichen/p/15072050.html
Copyright © 2011-2022 走看看