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 }