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\n",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 }

 

posted @ 2019-02-22 10:39  陈星卿  阅读(161)  评论(0编辑  收藏  举报