zoukankan      html  css  js  c++  java
  • bzoj1912【Apio2010】patrol 巡逻

     


    题解:

            显然需要分类讨论了,首先理解k==0即原图时按照dfs序来说 , 每条边至少走两次;

            k==1,相当于可以省去dfs回溯时第二次走过某条路径的浪费,所以答案是k==0的答案-直径 ;

            k==2,和k==1同理,答案是k==0时的答案-两条边不相交的链的最大和,先做一次直径,将直径上的边边权都赋值为取为相反数,再做一次直径即可;(应该边权不只有1也是适用的吧,注意第二次的边权有负值只能用dp求直径)      

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 const int N=100010;
     4 int n,k,o=2,hd[N],mx,mx1,mx2,s1[N],s2[N],dia;
     5 struct Edge{int v,nt,w;}E[N<<1];
     6 void adde(int u,int v,int w){
     7     E[o]=(Edge){v,hd[u],w};hd[u]=o++;
     8     E[o]=(Edge){u,hd[v],w};hd[v]=o++;
     9 }
    10 int dfs(int u,int fa){
    11     int mx1=0,mx2=0;
    12     for(int i=hd[u];~i;i=E[i].nt){
    13         int v=E[i].v;
    14         if(v==fa)continue;
    15         int w = E[i].w + dfs(v,u);
    16         if(w>mx1)mx2=mx1,s2[u]=s1[u],mx1=w,s1[u]=i;
    17         else if(w>mx2)mx2=w,s2[u]=i;
    18     }
    19     if(mx1+mx2>dia)mx=u,dia=mx1+mx2;
    20     return mx1;
    21 }
    22 int main(){
    23     freopen("bzoj1912.in","r",stdin);
    24     freopen("bzoj1912.out","w",stdout);
    25     scanf("%d%d",&n,&k);
    26     memset(hd,-1,sizeof(hd));
    27     for(int i=1,u,v;i<n;i++){
    28         scanf("%d%d",&u,&v);
    29         adde(u,v,1);
    30     }
    31     int ans=(n-1)<<1;
    32     dia=0;dfs(1,0);
    33     ans=ans-dia+1;
    34     if(k==2){
    35         for(int i=s1[mx];i;i=s1[E[i].v])E[i].w=E[i^1].w=-1;
    36         for(int i=s2[mx];i;i=s1[E[i].v])E[i].w=E[i^1].w=-1;
    37         dia=0;dfs(1,0);
    38         ans=ans-dia+1;
    39     }
    40     printf("%d
    ",ans);
    41     return 0;
    42 }
    bzoj1912
  • 相关阅读:
    定位公众号页面,跳转之后 vuejs 失效问题
    Java发展前景与职业方向解析
    Java中BIO,NIO,AIO的理解
    Java中最常见的十道面试题
    java策略模式
    细思极恐-你真的会写java吗?
    Java中最常见的十道面试题
    细思极恐-你真的会写java吗?
    如何突破 Java 程序员的分水岭
    35 个 Java 代码性能优化总结
  • 原文地址:https://www.cnblogs.com/Paul-Guderian/p/10205101.html
Copyright © 2011-2022 走看看