zoukankan      html  css  js  c++  java
  • codevs 2756树上的路径

    题意:

    2756 树上的路径

     

     时间限制: 3 s
     空间限制: 128000 KB
     题目等级 : 大师 Master 
     
    题目描述 Description

    给出一棵树,求出最小的k,使得,且在树中存在路径P,使得k>= S 且 k <=E. (k为路径P上的边的权值和)

    输入描述 Input Description

    第一行给出N,S,E,N代表树的点数,S,E如题目描述一致

    下面N-1行给出这棵树的相邻两个节点的边及其权值W

    输出描述 Output Description

    输出一个整数k,表示存在路径P,并且路径上的权值和 K>=S , k<=E,若无解输出-1

    样例输入 Sample Input

    5 10 40

    2 4 80

    2 3 57

    1 2 16

    2 5 49

    样例输出 Sample Output

    16

    数据范围及提示 Data Size & Hint

    边权W<=10000,

    保证答案在int(longint)范围内,且|E-S|<=50,

    树上点的个数N<=30000

    ————————————————————————————————————————————————————————

    求树上一条路径,长度k在S到E之间,且k最小。

    方法为从小到大枚举k的值,如果长度不超过k的点对数比长度不超过k-1的点对数多则一定存在长度为k的点对,则输出k并退出。

    1、如果S到E的区间比较大,则可以使用二分,但是本题中只有50,可以依次枚举。

    2、查找点对数为树上的点分治,和上一题相同。

    3、注意init()的位置,这个地方出了错……

    ————————————————————————————————————————————————————————

      1 //codevs 2756鏍戜笂鐨勮矾寰?
      2 #include<cstdio>
      3 #include<iostream>
      4 #include<cstring>
      5 #include<algorithm>
      6 
      7 using namespace std;
      8 const int maxn=30010;
      9 int n,S,E;
     10 struct edge
     11 {
     12     int u,v,w,next;
     13 }e[2*maxn];
     14 int head[maxn],js=0,mi,jst,root;
     15 bool vis[maxn];
     16 int siz[maxn],mx[maxn],dis[maxn];
     17 int ans,preans,k;
     18 void readint(int &x)
     19 {
     20     char c=getchar();
     21     int f=1;
     22     for(;c>'9'||c<'0';c=getchar())if(c=='-')f=-f;
     23     x=0;
     24     for(;c<='9'&&c>='0';c=getchar())x=x*10+c-'0';
     25     x=x*f;
     26 }
     27 void addage(int u,int v,int w)
     28 {
     29     e[++js].u=u;e[js].v=v;e[js].w=w;
     30     e[js].next=head[u];head[u]=js;
     31 }
     32 void init()
     33 {
     34     memset(vis,0,sizeof(vis));
     35     ans=0;
     36 }
     37 void dfssize(int u,int f)
     38 {
     39     siz[u]=1;
     40     mx[u]=0;
     41     for(int i=head[u];i;i=e[i].next)
     42     {
     43         int v=e[i].v;
     44         if(v!=f && !vis[v])
     45         {
     46             dfssize(v,u);
     47             siz[u]+=siz[v];
     48             if(siz[v]>mx[u])mx[u]=siz[v];
     49         }
     50     }
     51 }
     52 void dfsroot(int r,int u,int f)
     53 {
     54     if(siz[r]-siz[u]>mx[u])mx[u]=siz[r]-siz[u];
     55     if(mx[u]<mi)
     56     {
     57         mi=mx[u];
     58         root=u;
     59     }
     60     for(int i=head[u];i;i=e[i].next)
     61     {
     62         int v=e[i].v;
     63         if(v!=f && !vis[v])
     64             dfsroot(r,v,u);
     65     }
     66 }
     67 void dfsdis(int u,int d,int f)
     68 {
     69     dis[jst++]=d;
     70     for(int i=head[u];i;i=e[i].next)
     71     {
     72         int v=e[i].v;
     73         if(v!=f && !vis[v])dfsdis(v,d+e[i].w,u);
     74     }
     75 }
     76 int calc(int u,int d)
     77 {
     78     jst=0;
     79     dfsdis(u,d,0);
     80     int dds=0;
     81     sort(dis,dis+jst);
     82     int i=0,j=jst-1;
     83     while(i<j)
     84     {
     85         while(dis[i]+dis[j]>k && i<j)j--;
     86         dds+=j-i;
     87         i++;
     88     }
     89     return dds;
     90 }
     91 void dfs(int u)
     92 {
     93     mi=n;
     94     dfssize(u,0);
     95     dfsroot(u,u,0);
     96     ans+=calc(root,0);
     97     vis[root]=1;
     98     for(int i=head[root];i;i=e[i].next)
     99     {
    100         int v=e[i].v;
    101         if(!vis[v])
    102         {
    103             ans-=calc(v,e[i].w);
    104             dfs(v);
    105         }
    106     }
    107 }
    108 int main()
    109 {
    110     readint(n);readint(S);readint(E);
    111     for(int u,v,w,i=1;i<n;i++)
    112     {
    113         readint(u);readint(v);readint(w);
    114         addage(u,v,w);addage(v,u,w);
    115     }
    116     init();
    117     k=S-1;
    118     dfs(1);    
    119     for(int i=S;i<=E;i++)
    120     {
    121         preans=ans;
    122         init();
    123         k=i;
    124         dfs(1);
    125         if(ans>preans)
    126         {
    127             printf("%d\n",i);
    128             return 0;
    129         }
    130     }
    131     printf("-1\n");
    132     return 0;
    133 }
    View Code
  • 相关阅读:
    视频: 不抱怨才有今天的马云---励志演讲
    ArcGIS图框工具5.2发布,支持ArcGIS10.0,10.110.2,支持国家2000坐标系
    arcgis 10.2 安装教程(含下载地址)
    delete
    基金销售牌照火热的背后,基金销售牌照、基金支付牌照
    快递业务经营许可证企业信息(截止2016.6.30)
    1月北上广P2P平台之最 平台数成交量现双降
    公募基金牌照:谁在布局?
    delete
    各地互联网小贷牌照申请全揭秘
  • 原文地址:https://www.cnblogs.com/gryzy/p/6169826.html
Copyright © 2011-2022 走看看