luogu4186 [USACO18JAN]Cow at Large G

http://www.elijahqi.win/2018/02/02/luogu4186-usaco18jancow-at-large-g/
题目描述

Cornered at last, Bessie has gone to ground in a remote farm. The farm consists of

NN

N barns (

2≤N≤1052 \leq N \leq 10^5

2≤N≤105 ) and

N−1N-1

N−1 bidirectional tunnels between barns, so that there is a unique path between every pair of barns. Every barn which has only one tunnel is an exit. When morning comes, Bessie will surface at some barn and attempt to reach an exit.

But the moment Bessie surfaces, the law will be able to pinpoint her location. Some farmers will then start at various exit barns, and attempt to catch Bessie. The farmers move at the same speed as Bessie (so in each time step, each farmer can move from one barn to an adjacent barn). The farmers know where Bessie is at all times, and Bessie knows where the farmers are at all times. The farmers catch Bessie if at any instant a farmer is in the same barn as Bessie, or crossing the same tunnel as Bessie. Conversely, Bessie escapes if she reaches an exit barn before any farms catch her.

Bessie is unsure about her chances of success, which depends on the number of farmers that the law is able to deploy. Given that Bessie surfaces at barn

KK

K , help Bessie determine the minimum number of farmers who would be needed to catch Bessie, assuming that the farmers distribute themselves optimally among the exit barns.
输入输出格式

输入格式:

The first line of the input contains

NN

N and

KK

K . Each of the following

N−1N-1

N−1 lines specify two integers, each in the range

1…N1 \ldots N

1…N , describing a tunnel between two barns.

输出格式:

Please output the minimum number of farmers needed to ensure catching Bessie.
输入输出样例

输入样例#1: 复制

7 1
1 2
1 3
3 4
3 5
4 6
5 7

输出样例#1: 复制

3

题意:求给定一个点 使得他无法走到叶子节点我需要在叶子节点上安排的最小人数 并且我叶子节点上的人可以走动 但和牛的走动速度一样 尝试画图之后可以发现如果我这个节点控制的叶子节点最近的那个走到这里比bessy走到这里还要近说明我这里放一个即可 如果不行说明我需要递归下去去做 使得可以被封死 那么显然变成了一个子问题就树形dp搞一下 一遍dfs维护最小值 还有距离 比较下直接更新答案即可

#include
#include
#include
#define N 110000
using namespace std;
inline char gc(){
    static char now[1<<16],*S,*T;
    if (T==S){T=(S=now)+fread(now,1,1<<16,stdin);if (T==S) return EOF;}
    return *S++;
}
inline int read(){
    int x=0,f=1;char ch=gc();
    while(ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=gc();}
    while(ch<='9'&&ch>='0') x=x*10+ch-'0',ch=gc();
    return x*f;
}
struct node{
    int y,next;
}data[N<<1];
int n,k,ans,dp[N],min1[N],dis[N],num,h[N];
inline void dfs(int x,int fa){
    int tmp=0,nm=0;
    for (int i=h[x];i;i=data[i].next){
        int y=data[i].y;if (y==fa) continue;++nm;dis[y]=dis[x]+1;dfs(y,x);tmp+=dp[y];
    }if (!nm) min1[x]=0;min1[fa]=min(min1[fa],min1[x]+1);if(dis[x]>=min1[x]) dp[x]=1;else dp[x]=tmp;
}
int main(){
//  freopen("atlarge.in","r",stdin);
//  freopen("atlarge.out","w",stdout);
    n=read();k=read();memset(min1,0x3f,sizeof(min1));
    for (int i=1;iint x=read(),y=read();
        data[++num].y=y;data[num].next=h[x];h[x]=num;
        data[++num].y=x;data[num].next=h[y];h[y]=num;
    }
    for (int i=h[k];i;i=data[i].next){
        int y=data[i].y;dis[y]=1;dfs(y,k);ans+=dp[y];
    }printf("%d\n",ans);
    return 0;
}

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