luogu P3629 [APIO2010]巡逻

#include <bits/stdc++.h>
using namespace std;
const int maxn = 100005;
const int maxm = 200005;
int he[maxn],ver[maxm],ne[maxm],cost[maxm],tot=1;
void add( int x,int y,int z ){
    ver[++tot] = y;
    ne[tot] = he[x];
    he[x] = tot;
    cost[tot] = z;
}
int son1[maxn],son2[maxn],h1[maxn],h2[maxn],res,s;
void dfs( int x,int f ){
    for( int cure = he[x];cure;cure = ne[cure] ){
        int y = ver[cure];
        if( y == f ) continue;
        dfs(y,x);
        int cur = h1[y]+cost[cure];
        if( h2[x] < cur ) {
            h2[x] = cur;
            son2[x] = cure;
            if (h2[x] > h1[x]) {
                swap(h1[x], h2[x]);
                swap(son1[x], son2[x]);
            }
        }
        if(res < h1[x]+h2[x])
        res = h1[x]+h2[x],s = x ;
    }
}
int main(){
    int n,k,x,y;
    scanf("%d%d",&n,&k);
    for( int i = 1;i < n;i++ ){
        scanf("%d%d",&x,&y);
        add(x,y,1);add(y,x,1);
    }
    memset( son1,0,sizeof(int)*(n+1) );
    memset( son2,0,sizeof(int)*(n+1) );
    memset( h1,0,sizeof(int)*(n+1) );
    memset(h2,0,sizeof(int)*(n+1));
    res = 0;
    dfs(1,0);
    x = s;
    int ans = (n-1)*2 -res+1;
    if( k == 1 ){
        printf("%d\n",ans);
        return 0;
    }
    for( int i = son1[x];i;i = son1[ver[i]] ){
        cost[i] = cost[i^1] = -1;
    }
    for( int i = son2[x];i;i = son1[ver[i]] ){
        cost[i] = cost[i^1] = -1;
    }
    memset( son1,0,sizeof(int)*(n+1) );
    memset( son2,0,sizeof(int)*(n+1) );
    memset( h1,0,sizeof(int)*(n+1) );
    memset(h2,0,sizeof(int)*(n+1));
    res = 0;
    dfs(1,0);
    ans = ans -res +1;
    printf("%d\n",ans);
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值