题意:在一棵以0为根的树中,Bob和Alice从0开始轮流选边。Bob想使路径总长度尽量大,Alice想使路径总长度尽量小。寻找路径长度在[L,R]区间内最优操作解,如果不存在,输出Oh my god!
解法:在dp过程中需要加上[L,R]区间的限制!用优先队列挑出满足区间范围条件的子树最优解
#include <stdio.h>
#include <string.h>
#include <set>
#include <map>
#include <algorithm>
#include<vector>
#include<iostream>
#include<queue>
#define ll long long
#define INF 0x3f3f3f3f
using namespace std ;
const ll maxn = 500000+10;
ll n,l,r;
struct Edge{
ll to,next,w;
}edge[maxn<<1];
ll head[maxn],tot;
void add(ll u,ll v,ll w){
edge[tot].to=v,edge[tot].next=head[u],edge[tot].w=w;
head[u]=tot++;
}
ll dfs(ll u,ll sum,ll fa,ll f){
bool flag=false;
ll cnt=0;
priority_queue<ll> qn1;
priority_queue<ll,vector<ll>,greater<ll> > qn2;
for(ll i=head[u];i!=-1;i=edge[i].next){
ll v=edge[i].to,w=edge[i].w;
if(v==fa) continue;
flag=true;
if(f==1){
ll a=dfs(v,sum+w,u,0);
if(a!=-1&&a+w+sum>=l&&a+w+sum<=r) { qn1.push(a+w); cnt++; }
}
else{
ll a=dfs(v,sum+w,u,1);
if(a!=-1&&a+w+sum>=l&&a+w+sum<=r) { qn2.push(a+w); cnt++; }
}
}
if(!flag) return 0;
if(!cnt) return -1;
if(f==1) return qn1.top();
else return qn2.top();
}
int main(){
//freopen("a.txt","r",stdin);
while(scanf("%lld%lld%lld",&n,&l,&r)!=EOF){
memset(head,-1,sizeof(head)),tot=0;
for(ll i=1;i<n;i++){
ll u,v,w;
scanf("%lld%lld%lld",&u,&v,&w);
add(u,v,w),add(v,u,w);
}
ll ans=dfs(0,0,-1,1);
if(ans==-1) printf("Oh, my god!\n");
else printf("%lld\n",ans);
}
}