zoukankan      html  css  js  c++  java
  • poj1741_Tree(树的点分治入门题)

    题目链接:poj1741_Tree

    题意:

    给你一颗n个节点的树,每条边有一个值,问有多少点对(u,v),满足u->v的最短路径小于k。

    题解:

    典型的树的分治,板子题。

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 #define F(i,a,b) for(int i=a;i<=b;++i)
     5 using namespace std;
     6 
     7 const int N=1e4+7;
     8 
     9 int n,k,g[N],v[N*2],nxt[N*2],w[N*2],ed,ans;
    10 int vis[N],size[N],mx[N],mi,dis[N],tot,root;
    11 
    12 inline void adg(int x,int y,int z){v[++ed]=y,w[ed]=z,nxt[ed]=g[x],g[x]=ed;}
    13 void init(){F(i,1,n)g[i]=0,vis[i]=0;ed=ans=0;}
    14 
    15 void dfs_size(int u,int fa)
    16 {
    17     size[u]=1,mx[u]=0;
    18     for(int i=g[u];i;i=nxt[i])
    19         if(v[i]!=fa&&!vis[v[i]])
    20         {
    21             dfs_size(v[i],u),size[u]+=size[v[i]];
    22             if(size[v[i]]>mx[u])mx[u]=size[v[i]];
    23         }
    24 }
    25 
    26 void dfs_root(int r,int u,int fa)
    27 {
    28     if(size[r]-size[u]>mx[u])mx[u]=size[r]-size[u];
    29     if(mx[u]<mi)mi=mx[u],root=u;
    30     for(int i=g[u];i;i=nxt[i])
    31         if(v[i]!=fa&&!vis[v[i]])
    32             dfs_root(r,v[i],u);
    33 }
    34 
    35 void dfs_dis(int u,int d,int fa)
    36 {
    37     dis[++tot]=d;
    38     for(int i=g[u];i;i=nxt[i])
    39         if(v[i]!=fa&&!vis[v[i]])
    40             dfs_dis(v[i],d+w[i],u);
    41 }
    42 
    43 int calc(int u,int d)
    44 {
    45     int ans=0;
    46     tot=0,dfs_dis(u,d,0);
    47     sort(dis+1,dis+1+tot);
    48     int i=1,j=tot;
    49     while(i<j)
    50     {
    51         while(dis[i]+dis[j]>k&&i<j)j--;
    52         ans+=j-i,i++;
    53     }
    54     return ans;
    55 }
    56 
    57 void dfs(int u=1)
    58 {
    59     mi=n,dfs_size(u,0);
    60     dfs_root(u,u,0);
    61     ans+=calc(root,0),vis[root]=1;
    62     for(int i=g[root];i;i=nxt[i])
    63         if(!vis[v[i]])ans-=calc(v[i],w[i]),dfs(v[i]);
    64 }
    65 
    66 int main()
    67 {
    68     while(~scanf("%d%d",&n,&k)&&n+k!=0)
    69     {
    70         init();
    71         F(i,1,n-1)
    72         {
    73             int x,y,z;
    74             scanf("%d%d%d",&x,&y,&z);
    75             adg(x,y,z),adg(y,x,z);
    76         }
    77         dfs();
    78         printf("%d
    ",ans);
    79     }
    80     return 0;
    81 }
    View Code
  • 相关阅读:
    13 款开源的全文检索引擎
    Laravel5.5 Jwt 1.0 beta 配置
    Laravel SQL 查询语句集锦
    laravel在中间件内生成的变量如何传到控制器
    laravel中的自定义函数的加载和第三方扩展库加载
    laravel5.5 dingo/api+jwt-auth
    微信小程序之使用checkbox
    微信小程序之使用wx:for遍历循环
    微信小程序之页面导航栏
    微信小程序之数据缓存
  • 原文地址:https://www.cnblogs.com/bin-gege/p/6069486.html
Copyright © 2011-2022 走看看