zoukankan      html  css  js  c++  java
  • USACO 2015 December Contest Max Flow (bzoj4390)

    给定一棵有N个点的树,所有节点的权值都为0。

    有K次操作,每次指定两个点s,t,将s到t路径上所有点的权值都加一。

    请输出K次操作完毕后权值最大的那个点的权值。


    很裸的一道题,树剖+查分 将val[x]+1,val[y]+1,val[lca]-1,val[fa[lca]]-1

    最后统计就好了。

    #include <stdio.h>
    #include <algorithm>
    #include <cstring>
    #include <cmath>
    #include <queue>
    #include <vector>
    using namespace std;
    const int maxn=50000+10;
    const int maxm=500000+10;
    int n,k,point,ans; 
    int size[maxn],fa[maxn],head[maxn],dep[maxn],bel[maxn],val[maxn];
    struct hh
    {
      int v,next;
    }e[maxm*2];
    template <class T> void read(T&x)
    {
      x=0;char c=getchar();int f=0;
      while(c<'0'||c>'9'){f|=(c=='-');c=getchar();}
      while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+(c^48),c=getchar();
      x=f?-x:x;
    }
    void add(int u,int v)
    {
      e[++point].v=v;e[point].next=head[u];head[u]=point;
      e[++point].v=u;e[point].next=head[v];head[v]=point;
    }
    void dfs(int x)
    {
      size[x]=1;
      for(int i=head[x];~i;i=e[i].next)
      {
          if(e[i].v==fa[x])continue;
          fa[e[i].v]=x;
          dep[e[i].v]=dep[x]+1;
          dfs(e[i].v);
          size[x]+=size[e[i].v];
      }
      return;
    }
    void dfs1(int x,int chain)
    {
      int k=0;bel[x]=chain;
      for(int i=head[x];~i;i=e[i].next)
       if(dep[e[i].v]>dep[x]&&size[e[i].v]>size[k])k=e[i].v;
      if(!k)return;
      dfs1(k,chain);
      for(int i=head[x];~i;i=e[i].next)
       if(dep[e[i].v]>dep[x]&&e[i].v!=k)
        dfs1(e[i].v,e[i].v);
    }
    void dfs2(int x)
    {
      for(int i=head[x];~i;i=e[i].next)
       if(dep[e[i].v]>dep[x])
       {
            dfs2(e[i].v);
            val[x]+=val[e[i].v];
       }
      if(ans<val[x])ans=val[x];
      return;
    }
    int lca(int x,int y)
    {
      while(bel[x]!=bel[y])
      {
          if(dep[bel[x]]<dep[bel[y]]){x^=y;y^=x;x^=y;}
          x=fa[bel[x]];
      }
      return dep[x]<=dep[y]?x:y;
    }
    int main()
    {
      memset(head,-1,sizeof(head));
      dep[1]=1;
      read(n);read(k);
      for(int i=1;i<n;i++)
      {
        int u,v;read(u);read(v);
        add(u,v);
      }
      dfs(1);
      dfs1(1,1);
      for(int i=1;i<=k;i++)
      {
        int x,y;read(x);read(y);
        int lf=lca(x,y);
        val[x]++;val[y]++;
        val[lf]--;val[fa[lf]]--;
      }
      dfs2(1);
      printf("%d",ans);
      return 0;
    }
    View Code
  • 相关阅读:
    Android进阶——Volley+Https给你的安卓应用加上SSL证书(转)
    VSFTP上传不了
    mysql主从同步配置
    EditText插入表情(字符串)到光标所在位置
    js实现监听页面滚动实现图片延迟加载
    android开发技巧——仿新版QQ锁屏下弹窗(转)
    [原创]JAVA技巧:去除ArrayList<Object>里面的重复记录
    [原创]JAVA号码工具类:实现手机固话号码判断与区号截取
    [原创]FreeSWITCH实现多人来电思路
    [原创]Linux实现服务延迟启动
  • 原文地址:https://www.cnblogs.com/new-hand/p/9285027.html
Copyright © 2011-2022 走看看