zoukankan      html  css  js  c++  java
  • [搜索]Sugigma: The Showdown

    Description

    从前有一只巨大的鹿想喝水,老爷爷为了恢复环境,想阻止这只巨大的鹿喝水。

    老爷爷和鹿同在一片草地里。这片草地里一共有N个水池子,鹿会在水池之间移动,而老爷爷则会乘坐德国进口的高科技糹乙万恶木馬,在水池间追赶这头巨大多喝水的鹿。水池之间连了N−1条红色边和N−1条蓝色边,分别构成两棵树。巨大的鹿只会沿着红色边行走,而高科技糹乙万恶木馬只会沿着蓝色边行走。

    走一条边是很耗时间的,在每个人走每条边的时间里,巨大多喝水的鹿都会喝掉1吨水(鹿在行走过程中也能喝水,这些水是用即可科技转化空气产生的)。初始时,巨大的鹿位于X号水池,老爷爷位于Y号水池。巨大的鹿和高科技糹乙万恶木馬会轮流行走,鹿先走一步,万恶木馬走第二步,鹿再走第三步,······,以此类推,每一步都会选择最优策略。当然,轮到一个人(或鹿)走的时候,他也可以选择不走,而是坐在原地休息,这段时间里鹿也会喝掉1吨的水,休息完之后就又轮到对方了。当老爷爷和鹿位于同一个水池时,鹿就会被老爷爷深度烧烤,从而再也无法喝水。当然,也可能存在老爷爷永远无法追上鹿的情况,这种时候老爷爷就会伤筋动骨。

    巨大的鹿的目标是喝尽可能多的水,而老爷爷的目标是让它喝尽可能少的水。鹿想知道它最多能喝多少水,如果你能帮他算出来,它会带你到饭店换一台手机。

    Input

    第一行包含三个整数N,X,Y。
    接下来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);
    }
    View Code
  • 相关阅读:
    Java集合源码分析(一)
    EffectiveJava——请不要在代码中使用原生态类型
    Dubbo初探
    EffectiveJava——用函数对象表示策略
    EffectiveJava——类层次优于标签类
    notebook1.md
    NoteBook学习(二)-------- Zeppelin简介与安装
    Spark2.0学习(三)--------核心API
    Spark2.0学习(二)--------RDD详解
    Spark2.0学习(一)--------Spark简介
  • 原文地址:https://www.cnblogs.com/mastervan/p/11545789.html
Copyright © 2011-2022 走看看