zoukankan      html  css  js  c++  java
  • bzoj 1912: [Apio2010]patrol 巡逻

    Description

    solution

    正解:贪心+DP
    首先对于K=1的情况我们可以发现答案是 ((n-1)*2)-树的直径+1

    K=2同理,我们也要再找出一条不相交的树的直径,然后怎么保证不相交呢?
    其实只需要把第一次求得的直径上的点赋值为-1即可
    如果一条边再两次都出现,就相互抵消了,去掉抵消的部分,就完美的形成了不相交的两条链了,非常巧妙
    另外,两遍dfs求直径的方法在有负权的情况下是用不了了,需要DP求解,具体是记录最长链和次长链 相加

    #include <algorithm>
    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include <cstdio>
    #include <cmath>
    #define RG register
    #define il inline
    #define iter iterator
    #define Max(a,b) ((a)>(b)?(a):(b))
    #define Min(a,b) ((a)<(b)?(a):(b))
    using namespace std;
    const int N=100005;
    int n,K,head[N],to[N<<1],nxt[N<<1],dis[N<<1],num=1;
    il void link(int x,int y,int z){
       nxt[++num]=head[x];to[num]=y;dis[num]=z;head[x]=num;}
    int f[N][2],ans=0,ansid=0,maxid[N],cmax[N];
    il void dfs(RG int x,int last){
       RG int u,tmp;
       for(int i=head[x];i;i=nxt[i]){
          u=to[i];if(u==last)continue;
          dfs(u,x);tmp=f[u][0]+dis[i];
          if(tmp>f[x][0])
             cmax[x]=maxid[x],maxid[x]=i,f[x][1]=f[x][0],f[x][0]=tmp;
          else if(tmp>f[x][1])f[x][1]=tmp,cmax[x]=i;
       }
       if(f[x][0]+f[x][1]>=ans)ans=f[x][0]+f[x][1],ansid=x;
    }
    il void Rev(int i){dis[i]=dis[i^1]=-1;}
    void solve(){
       Rev(maxid[ansid]);Rev(cmax[ansid]);
       RG int now=to[maxid[ansid]];
       while(maxid[now]){
          Rev(maxid[now]);
          now=to[maxid[now]];
       }
       now=to[cmax[ansid]];
       while(maxid[now]){
          Rev(maxid[now]);
          now=to[maxid[now]];
       }
    }
    void Clear(){
       memset(f,0,sizeof(f));memset(maxid,0,sizeof(maxid));
       memset(cmax,0,sizeof(cmax));ans=0;ansid=0;
    }
    void work()
    {
       int x,y,ret=0;
       scanf("%d%d",&n,&K);
       for(RG int i=1;i<n;i++){
          scanf("%d%d",&x,&y);
          link(x,y,1);link(y,x,1);
       }
       ret+=(n-1)<<1;dfs(1,1);ret-=ans-1;
       if(K==1){printf("%d
    ",ret);return ;}
       solve();Clear();dfs(1,1);ret-=ans-1;
       printf("%d
    ",ret);
    }
     
    int main()
    {
        work();
        return 0;
    }
    
  • 相关阅读:
    【Jest】笔记二:Matchers匹配器
    【爬虫】如何用python+selenium网页爬虫
    【mysql-server】遇到的坑
    【puppeteer】前端自动化初探(一)
    强制360谷歌使用谷歌内核
    实时获取input输入框中的值
    什么是单页面
    如何更改Apache的根目录指向
    iphone上点击div会出现半透明灰色背景以及margin失效
    event.currentTarget和event.target的区别
  • 原文地址:https://www.cnblogs.com/Hxymmm/p/7712761.html
Copyright © 2011-2022 走看看