zoukankan      html  css  js  c++  java
  • P2680 运输计划

      由题可知,我们要使最长的路径尽可能小,那么就二分最长的路径,把路径按升序排列,使其具有单调性,

    然后把所有长度>mid的路径处理出来,进行树上差分,处理出这些路径都经过的最大的边,if maxpath - maxedge > mid then return false;

      1 /*
      2     Author:TYD 
      3     Date: 22/02/19 08:54
      4     Description:二分+树上边差分(LCA树剖版) 
      5 */
      6 #include <bits/stdc++.h>
      7 #define read read()
      8 #define up(i,l,r) for(register int i = (l);i <= (r);i++)
      9 #define down(i,l,r) for(register int i = (l);i >= (r);i--)
     10 #define traversal_vedge(i) for(register int i = head[u]; i ;i = e[i].nxt)
     11 #define ll long long
     12 using namespace std;
     13 int read
     14 {
     15     int x = 0, f = 1; char ch = getchar();
     16     while(ch < 48 || ch > 57) {if(ch == '-')f = -1; ch = getchar();}
     17     while(ch >=48 && ch <=57) {x = 10 * x + ch - 48;ch = getchar();}
     18     return x * f; 
     19 }
     20 //-----------------------------------------------------------------
     21 
     22 int n,m;
     23 const int N = 300005;
     24 struct edge{
     25     int v,w,nxt;
     26 }e[N<<1];int tot,head[N];
     27 
     28 void add(int u,int v,int w){e[++tot] = (edge){v,w,head[u]}; head[u] = tot; }
     29 
     30 
     31 
     32 int dep[N],size[N],fa[N],top[N],dis[N];
     33 int cnt[N],maxe,num,init[N],l,r;
     34 
     35 
     36 
     37 struct path{
     38     int u,v,dis,lca;
     39     bool operator < (const path &x) const{
     40         return dis < x.dis;
     41     }
     42 }p[N];
     43 
     44 void dfs_tree(int u)
     45 {
     46     traversal_vedge(i)
     47     {
     48         int v = e[i].v;
     49         if(v == fa[u]) continue;
     50         dfs_tree(v);
     51         cnt[u] += cnt[v];
     52     }
     53     if(cnt[u] == num) maxe = max(maxe,init[u]);
     54 }
     55 
     56 bool check(int maxpath)
     57 {
     58     memset(cnt,0,sizeof(cnt));
     59     maxe = num = 0;
     60     up(i,1,m)
     61     {
     62         if(p[i].dis <= maxpath) continue;
     63         
     64         cnt[p[i].u]++; cnt[p[i].v]++;
     65         cnt[p[i].lca] -= 2;
     66         num++;
     67     }
     68     dfs_tree(1);
     69     //up(i,1,n) if(cnt[i] == num) maxe = max(maxe,init[i]);
     70     return p[m].dis - maxe <= maxpath;
     71 }
     72 
     73 void binary_search()
     74 {
     75     l = 0;//,r = m;
     76     while(l <= r)
     77     {
     78         int mid = (l+r)>>1;
     79         if(check(mid))  r = mid - 1;
     80         else l = mid + 1;
     81     }
     82     printf("%d
    ",l);
     83 }
     84 //------------------------------------------------------
     85 void dfs(int u)
     86 {
     87     size[u] = 1; top[u] = u;
     88     dep[u] = dep[fa[u]]+1;
     89     int hson_id = 0,hson_size = 0;
     90     traversal_vedge(i)
     91     {
     92         int v = e[i].v;
     93         if(v == fa[u]) continue;
     94         fa[v] = u;
     95         dis[v] = dis[u] + e[i].w;
     96         init[v] = e[i].w;
     97         dfs(v);
     98         size[u] += size[v];
     99         if(size[v] > hson_size) hson_id = v,hson_size = size[v];
    100     }
    101     if(hson_id) top[hson_id] = u;
    102 }
    103 
    104 int find(int u)
    105 {
    106     if(u == top[u]) return u;
    107     top[u] = find(top[u]);
    108     return top[u]; 
    109 }
    110 
    111 int LCA(int x,int y)
    112 {
    113     if(find(x) != find(y))
    114     {
    115         if(dep[top[x]] > dep[top[y]]) return LCA(fa[top[x]],y);
    116         else return LCA(x,fa[top[y]]);
    117     }
    118     return dep[x] > dep[y]? y : x;
    119 }
    120 //--------------------------------------------------------------
    121 void work()
    122 {
    123     dfs(1);
    124     up(i,1,m)
    125     {
    126         int u = read,v = read;
    127         p[i].u = u; p[i].v = v;
    128         p[i].lca = LCA(u,v);
    129         p[i].dis = dis[u] + dis[v] - (dis[p[i].lca]<<1);
    130         r = max(r,p[i].dis);
    131     }
    132     sort(p+1,p+m+1);
    133     binary_search();
    134 }
    135 
    136 void readdata()
    137 {
    138     n = read; m = read;
    139     up(i,1,n-1)
    140     {
    141         int u = read,v = read,w = read;
    142         add(u,v,w);
    143         add(v,u,w);
    144     }
    145 }
    146 
    147 int main()
    148 {
    149     readdata();
    150     work();
    151     return 0;
    152 }
  • 相关阅读:
    无尽的冒险
    推荐一款好用的markdown编辑器,还可以引入vue主题
    你是微光
    Echarts 空心饼图示例
    vue + element-ui 制作tab切换(切换vue组件,踩坑总结)
    vue + element-ui 制作tab切换(适用于单页切换不同标记显示不同内容)
    Element UI 封装Table --> 实现动态创建表头和单元格数据(单元格内可动态增加非纯文本的内容)
    Element UI 封装Table --> 实现动态创建表头和单元格数据(无需写死表头和单元格数据)
    vue 部署到生产出现语法错误和css警告(Resource interpreted as Stylesheet but transferred with MIME type text/html: "www.aaa.com/cal/static/css/app.c06.css". vendor.4b6.js:1 Uncaught SyntaxError: Unexpected token '<')
    使用vue-cookies插件操作cookie
  • 原文地址:https://www.cnblogs.com/mzg1805/p/10416909.html
Copyright © 2011-2022 走看看