zoukankan      html  css  js  c++  java
  • [USACO18JAN] Cow at Large G (dfs)

    题目大意:有一只狐狸从给定的S点开始逃跑(出发),向叶节点移动以逃离这棵树,叶节点可能出现农民去抓捕狐狸,当农民和狐狸出现在同一个节点的时候,狐狸会被抓住,农民和狐狸移动速度相同,求抓捕狐狸所需要的最少农民数

    显然,当 u 节点的子树内存在一叶节点 i 满足deep[i]-deep[u]<=deep[u]时,说明 u 的子树能被守住

    即农民从 i 移动到 u 所需要的时间小于等于狐狸从出发点移动到 u 的时间

    第一遍dfs预处理出每个节点的深度dep,以及每个节点的子树内深度最小的叶节点的深度mindep(代码中简化为mi)

    第二遍dfs求答案,只要某个节点能被其子树内某个叶节点守住,那么它子树内其它节点就不用考虑了,return 1

    但并不能从S点直接开始第二个dfs,而是从S点直接连接的所有节点开始,因为狐狸和农民移动速度一样,如果按之前的方法,狐狸可能会往相反方向跑,导致农民无法追上狐狸

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #define N 100005
     5 #define inf 0x3f3f3f3f
     6 #define maxn 1000010
     7 using namespace std;
     8 //re
     9 
    10 int n,S,cte;
    11 int head[N],dep[N],mi[N],inc[N];
    12 struct Edge{int to,nxt;}edge[N*2];
    13 void ae(int u,int v){
    14     cte++;edge[cte].to=v,inc[v]++;
    15     edge[cte].nxt=head[u],head[u]=cte;
    16 }
    17 void dfs1(int u,int fa)
    18 {
    19     if(inc[u]==1) {mi[u]=dep[u];return;}
    20     for(int j=head[u];j;j=edge[j].nxt){
    21         int v=edge[j].to;
    22         if(v==fa) continue;
    23         dep[v]=dep[u]+1;
    24         dfs1(v,u);
    25         mi[u]=min(mi[u],mi[v]);
    26     }
    27 }
    28 int dfs2(int u,int fa)
    29 {
    30     int ans=0;
    31     if(mi[u]-dep[u]<=dep[u])
    32         return 1;
    33     for(int j=head[u];j;j=edge[j].nxt){
    34         int v=edge[j].to;
    35         if(v==fa) continue;
    36         ans+=dfs2(v,u);
    37     }
    38     return ans;
    39 }
    40 
    41 int main()
    42 {
    43     scanf("%d%d",&n,&S);
    44     int x,y,ans=0;
    45     for(int i=1;i<n;i++)
    46         scanf("%d%d",&x,&y),ae(x,y),ae(y,x);
    47     memset(mi,0x3f,sizeof(mi));
    48     dfs1(S,-1);
    49     for(int j=head[S];j;j=edge[j].nxt){
    50         int v=edge[j].to;
    51         ans+=dfs2(v,S);
    52     }printf("%d
    ",ans);
    53     return 0;
    54 }
  • 相关阅读:
    About Face 摘录
    断言的使用
    C#中值传递和引用传递
    C++技巧之断言Assert
    About Face 一 目标导向设计
    About Face 二 设计行为与形态
    C++中引用传递与指针传递区别
    一个新的时代SoLoMo
    离散数学笔记算法部分
    汪教授的离散数学20110308 谓词与量词2
  • 原文地址:https://www.cnblogs.com/guapisolo/p/9785961.html
Copyright © 2011-2022 走看看