省选专练之避难向导

省选专练之避难向导_第1张图片

省选专练之避难向导_第2张图片

额树形DP+ST表倍增

按照区间最长链的思路树形DP

ST表倍增(我写的有点丑)

#include
using namespace std;
typedef int INT;
#define int long long
inline void read(int &x){
	x=0;
	int f=1;
	char ch=getchar();
	while(ch<'0'||ch>'9'){
		if(ch=='-')f=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9'){
		x=x*10+ch-'0';
		ch=getchar();
	}
	x*=f;
}
const int N=1e5+100;
struct Front_star{
	int u,v,w,nxt;
}e[N<<2];
int cnt=0;
int first[N];
void add(int u,int v,int w){
	cnt++;
	e[cnt].u=u;
	e[cnt].v=v;
	e[cnt].w=w;
	e[cnt].nxt=first[u];
	first[u]=cnt;
}
int n,m,a,b,c;
int F[N][2];
int son[N];
int dep[N]={};
int fa[N][21];
int st[N][21];
void DFS1(int u,int fat){
	fa[u][0]=fat;
	for(int i=first[u];i;i=e[i].nxt){
		int v=e[i].v;
		if(v==fat)continue;
		dep[v]=dep[u]+1;
		DFS1(v,u);
		if(F[v][0]+e[i].w>F[u][0]){
			F[u][1]=F[u][0];
			F[u][0]=F[v][0]+e[i].w;
			son[u]=v;
		}
		else 
			if(F[v][0]+e[i].w>F[u][1]){
				F[u][1]=F[v][0]+e[i].w;
			}
	}
}
int G[N];
void DFS2(int u,int fat,int len){
	if(u!=son[fat]){
		G[u]=max(G[u],F[fat][0]);
	}
	else{
		G[u]=max(G[u],F[fat][1]);
	}
	G[u]=max(G[u],G[fat])+len;
	for(int i=first[u];i;i=e[i].nxt){
		int v=e[i].v;
		if(v==fat)continue;
		DFS2(v,u,e[i].w);
	}
}
int val[N]={};
void Pre(){
	for(int i=1;i<=n;++i)st[i][0]=val[fa[i][0]];
	for(int i=1;i<=20;++i){
		for(int j=1;j<=n;++j){
			fa[j][i]=fa[fa[j][i-1]][i-1];
			st[j][i]=max(st[fa[j][i-1]][i-1],st[j][i-1]);
		}
	}
}
int GetLCA(int x,int y){
	if(dep[x]=0;i--){
		if(dep[x]-(1<=dep[y])x=fa[x][i];
	}
	if(x==y)return x;
	for(int i=20;i>=0;i--){
		if(fa[x][i]!=fa[y][i]){
			x=fa[x][i];
			y=fa[y][i];
		}
	}
	return fa[x][0];
}
int GetLow(int x,int d,int LCA,int Q){
	if(dep[x]<=dep[LCA])return -1;
	for(;dep[fa[x][d]]=0;i--){
		if(st[x][i]=0;i--){
		if(st[fa[x][i]][i]>=Q)x=fa[x][i];
	}
	return fa[x][0];
}
INT main(){
//	freopen("test.in","r",stdin);
	read(n);
	read(m);
	read(a);
	read(b);
	read(c);
	for(int i=1;i=q){
			ans=u;
		}
		if(ans==-1){
			int d=0;
			for(;(1<=q)ans=v;
		cout<

 

你可能感兴趣的:(动态规划)