[搜索]Sugigma: The Showdown
Description
从前有一只巨大的鹿想喝水,老爷爷为了恢复环境,想阻止这只巨大的鹿喝水。
老爷爷和鹿同在一片草地里。这片草地里一共有N个水池子,鹿会在水池之间移动,而老爷爷则会乘坐德国进口的高科技糹乙万恶木馬,在水池间追赶这头巨大多喝水的鹿。水池之间连了N−1条红色边和N−1条蓝色边,分别构成两棵树。巨大的鹿只会沿着红色边行走,而高科技糹乙万恶木馬只会沿着蓝色边行走。
走一条边是很耗时间的,在每个人走每条边的时间里,巨大多喝水的鹿都会喝掉1吨水(鹿在行走过程中也能喝水,这些水是用即可科技转化空气产生的)。初始时,巨大的鹿位于X号水池,老爷爷位于Y号水池。巨大的鹿和高科技糹乙万恶木馬会轮流行走,鹿先走一步,万恶木馬走第二步,鹿再走第三步,······,以此类推,每一步都会选择最优策略。当然,轮到一个人(或鹿)走的时候,他也可以选择不走,而是坐在原地休息,这段时间里鹿也会喝掉1吨的水,休息完之后就又轮到对方了。当老爷爷和鹿位于同一个水池时,鹿就会被老爷爷深度烧烤,从而再也无法喝水。当然,也可能存在老爷爷永远无法追上鹿的情况,这种时候老爷爷就会伤筋动骨。
巨大的鹿的目标是喝尽可能多的水,而老爷爷的目标是让它喝尽可能少的水。鹿想知道它最多能喝多少水,如果你能帮他算出来,它会带你到饭店换一台手机。
老爷爷和鹿同在一片草地里。这片草地里一共有N个水池子,鹿会在水池之间移动,而老爷爷则会乘坐德国进口的高科技糹乙万恶木馬,在水池间追赶这头巨大多喝水的鹿。水池之间连了N−1条红色边和N−1条蓝色边,分别构成两棵树。巨大的鹿只会沿着红色边行走,而高科技糹乙万恶木馬只会沿着蓝色边行走。
走一条边是很耗时间的,在每个人走每条边的时间里,巨大多喝水的鹿都会喝掉1吨水(鹿在行走过程中也能喝水,这些水是用即可科技转化空气产生的)。初始时,巨大的鹿位于X号水池,老爷爷位于Y号水池。巨大的鹿和高科技糹乙万恶木馬会轮流行走,鹿先走一步,万恶木馬走第二步,鹿再走第三步,······,以此类推,每一步都会选择最优策略。当然,轮到一个人(或鹿)走的时候,他也可以选择不走,而是坐在原地休息,这段时间里鹿也会喝掉1吨的水,休息完之后就又轮到对方了。当老爷爷和鹿位于同一个水池时,鹿就会被老爷爷深度烧烤,从而再也无法喝水。当然,也可能存在老爷爷永远无法追上鹿的情况,这种时候老爷爷就会伤筋动骨。
巨大的鹿的目标是喝尽可能多的水,而老爷爷的目标是让它喝尽可能少的水。鹿想知道它最多能喝多少水,如果你能帮他算出来,它会带你到饭店换一台手机。
Input
第一行包含三个整数N,X,Y。
接下来N−1行,每行两个整数描述红树中的一条边。
接下来N−1行,每行两个整数描述蓝树中的一条边。
接下来N−1行,每行两个整数描述红树中的一条边。
接下来N−1行,每行两个整数描述蓝树中的一条边。
Output
如果老爷爷能追上鹿,输出双方都在最优策略下时,鹿最多能喝掉最多吨水。否则输出"-1"。
Sample Input
## Sample Input 1
4 1 2
1 2
1 3
1 4
2 1
2 3
1 4
## Sample Input 2
3 3 1
1 2
2 3
1 2
2 3
## Sample Input 3
4 1 2
1 2
3 4
2 4
1 2
3 4
1 3
## Sample Input 4
4 2 1
1 2
3 4
2 4
1 2
3 4
1 3
## Sample Input 5
5 1 2
1 2
1 3
1 4
4 5
2 1
1 3
1 5
5 4
Sample Output
## Sample Output 1
4
## Sample Output 2
4
## Sample Output 3
2
## Sample Output 4
-1
## Sample Output 5
6
HINT
2≤N≤2×105
1≤X,Y≤N
存在20分的子任务,满足2≤N≤10。
存在30分的子任务(独立于上一个子任务),满足红树和蓝树结构一样。
分析
orz zzy
先加蓝树边先把蓝树DFS一遍处理出深度
不难想到如果鹿无法到达-1点则会在蓝树中能到达的最深的点处等死
-1点的要求:
与之相连的红树边的端点在蓝树中的距离大于2
加红树边时,把-1边删掉,标记-1点
然后对红树跑一遍BFS,在蓝树中不会被截胡的点才能继续扩张
然后判断一下-1点能否到达
最后找一个能到达的最深的点的,深度*2即为答案
#include <iostream> #include <cstdio> #include <queue> using namespace std; const int N=2e5+10; struct Edge { int u,v; }a[N]; struct Graph { int v,nx; bool w; }g[4*N]; int cnt,list[N],dep[N],dis[N],st[N],ed[N],tme,f[N]; bool spec[N],vis[N]; int n,s,t,ans; void Add(int u,int v,bool w) { g[++cnt]=(Graph){v,list[u],w};list[u]=cnt; g[++cnt]=(Graph){u,list[v],w};list[v]=cnt; } void DFS(int u,int fa) { dep[u]=dep[f[u]=fa]+1;st[u]=++tme; for (int i=list[u];i;i=g[i].nx) if (g[i].v!=fa) DFS(g[i].v,u); ed[u]=++tme; } int Solve(Edge a) { if (st[a.u]>st[a.v]) swap(a.u,a.v); if (ed[a.u]>ed[a.v]) if (dep[a.v]-dep[a.u]>2) return spec[a.u]=spec[a.v]=1; else return Add(a.u,a.v,1),1; if (f[a.u]==f[a.v]) return Add(a.u,a.v,1),1; spec[a.u]=spec[a.v]=1; } void BFS() { queue<int> q; q.push(s);vis[s]=1; while (!q.empty()) { int u=q.front();q.pop(); for (int i=list[u];i;i=g[i].nx) if (g[i].w&&!vis[g[i].v]) { dis[g[i].v]=dis[u]+1; if (dis[g[i].v]<dep[g[i].v]) q.push(g[i].v),vis[g[i].v]=1; } } } int main() { scanf("%d%d%d",&n,&s,&t); for (int i=1;i<n;i++) scanf("%d%d",&a[i].u,&a[i].v); for (int i=1,u,v;i<n;i++) scanf("%d%d",&u,&v),Add(u,v,0); dep[0]=-1;DFS(t,0); for (int i=1;i<n;i++) Solve(a[i]); BFS(); for (int i=1;i<=n;i++) if (vis[i]&spec[i]) return printf("-1"); for (int i=1;i<=n;i++) if (vis[i]) ans=max(ans,dep[i]<<1); printf("%d",ans); }
在日渐沉没的世界里,我发现了你。