单测试点时限: 2.5 秒

内存限制: 512 MB

EOJ Delivery Service Company handles a massive amount of orders in our nation. As is well known, our nation has ncities, with n−1 bi-directional paths connecting them, forming a tree. The length of the i-th path is wi, meaning that the time we have to spend walking through this path is wi.

Now, you, as the headquarter of EOJ, has somehow learned a magic spell. Each time you cast a spell on two paths, the lengths of these two paths magically swap with each other. You can do this magic as many times as you want(possibly none).

We have q orders waiting to be handled. The i-th order demands sending a package from city si to city ti. We kindly ask you to do your magic before all the deliveries start, such that the total time we have to spend on delivering these packages is minimized.

输入

The first line of the input contains one single integer n (1≤n≤2⋅105).

The next n−1 lines tell about the path information from path 1 to path n−1, the i-th of which contains three space-separated integers ui, vi and wi (1≤ui,vi≤n, ui≠vi, 1≤wi≤1000).

The next line contains one integer q (1≤q≤2⋅105).

The next q lines each contains two space-separated integers si and ti (1≤si,ti≤n,si≠ti).

输出

Output one integer, the minimum total time you can achieve.

样例

input
5
1 2 2
1 3 3
3 4 3
3 5 4
2
1 5
4 2
output
14

提示

In the example, we swap the weights between edge (1,2) and (1,3), so that the first order takes 2+4=6 time units to complete; the second order takes 2+3+3=8 time units. Thus the total time is 14.

题意就是给你一棵树,给你边(双向路径)和边权,边权是走这条路要花的时间,你有神奇的能力,可以交换任意两条边的边权,并且你可以无数次使用你的能力。然后给你m对点,表示要走路径<a,b>,要求你只能在他们开始走之前使用你的能力,问走完之后要花的最少时间是多少。

因为是走之前使用能力,所以可以提前处理出来,所以可以树上差分,所以树上差分,对边覆盖,把所有要走的路径先处理一下,sum[a]++,sum[b]++,sum[lca]-=2;然后Dfs遍历,求出来每条边走的次数,然后排个序,走的最多的路给最小的边权,就可以了。

代码:

 #include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstdlib>
using namespace std;
typedef long long ll;
const int maxn=2e5+; struct node{
int to,next;
}edge[maxn<<]; bool cmp(int a,int b)
{
return a>b;
}
int head[maxn<<],sum[maxn],dep[maxn],fa[maxn][],n,m,cnt,ans; void add(int x,int y){edge[++cnt].to=y,edge[cnt].next=head[x],head[x]=cnt;} void dfs(int u,int fath)//第一遍dfs,把信息处理出来
{
dep[u]=dep[fath]+,fa[u][]=fath;
for(int i=;fa[u][i];++i) fa[u][i+]=fa[fa[u][i]][i];
for(int i=head[u];i;i=edge[i].next){
int v=edge[i].to;
if(v!=fath) dfs(v,u);
}
} int LCA(int u,int v)//LCA
{
if(dep[u]>dep[v]) swap(u,v);
for(int i=;i>=;i--) if(dep[u]<=dep[v]-(<<i)) v=fa[v][i];
if(u==v) return u;
for(int i=;i>=;i--) if(fa[u][i]!=fa[v][i]) u=fa[u][i],v=fa[v][i];
return fa[u][];
} void Dfs(int u,int fath)//遍历求和
{
for(int i=head[u];i;i=edge[i].next){
int v=edge[i].to;
if(v==fath) continue;
Dfs(v,u);
sum[u]+=sum[v];
}
} int w[maxn]; int main()
{
int n;
scanf("%d",&n);
for(int i=;i<n;i++){
int x,y,v;
scanf("%d%d%d",&x,&y,&v);
add(x,y);add(y,x);
w[i]=v;
}
dfs(,);
int q;
scanf("%d",&q);
for(int i=;i<=q;i++){
int x,y;
scanf("%d%d",&x,&y);
int lca=LCA(x,y);
sum[x]++;sum[y]++;sum[lca]-=;
}
Dfs(,);
sort(w+,w++n-);
sort(sum+,sum+n+,cmp);
ll ans=;
for(int i=;i<n;i++){
ans+=(ll)w[i]*sum[i];
}
cout<<ans<<endl;
}

溜了。。。

EOJ Monthly 2018.8 D. Delivery Service-树上差分(边权/边覆盖)(边权转点权)(模板题)的更多相关文章

  1. EOJ Monthly 2018.7

    准备继续大学acm啦 又要开始愉快的码码码啦 第一次在华东师大OJ上面做题 看来EOJ上的积分体质是假的,我怎么一把上红??? A.数三角形 神tm的防AK题放在A,出题人很不友好啊... 先写了个暴 ...

  2. EOJ Monthly 2018.4

    A. ultmaster 的小迷妹们 Time limit per test: 2.0 seconds Memory limit: 256 megabytes ultmaster 男神和他的小迷妹们准 ...

  3. EOJ Monthly 2018.4 (E.小迷妹在哪儿(贪心&排序&背包)

    ultmaster 男神和小迷妹们玩起了捉迷藏的游戏. 小迷妹们都希望自己被 ultmaster 男神发现,因此她们都把自己位置告诉了 ultmaster 男神,因此 ultmaster 男神知道了自 ...

  4. [EOJ Monthly 2018.10][C. 痛苦的 01 矩阵]

    题目链接:C. 痛苦的 01 矩阵 题目大意:原题说的很清楚了,不需要简化_(:з」∠)_ 题解:设\(r_i\)为第\(i\)行中0的个数,\(c_j\)为第\(j\)列中0的个数,\(f_{i,j ...

  5. EOJ Monthly 2018.11 D. 猜价格

    猜价格 分两种情况讨论: k≤n,先猜至多 k 次 1,由于回答 <1 肯定是假的,所以可以把剩余系下是哪次错试出来,然后用至多 n 次搞定. k>n,每个数都猜两次,如果两次结果不一样, ...

  6. 【EOJ Monthly 2018.7】【D数蝌蚪】

    https://acm.ecnu.edu.cn/contest/92/problem/D/ D. 数蝌蚪 Time limit per test: 2.0 seconds Memory limit:  ...

  7. EOJ Monthly 2018.7 B.锐角三角形(数学几何+思维)

    描述 是否存在面积为S/2的整点锐角三角形?存在输出Yes并输出三个整点坐标,否则输出No. 注意如果存在输出的坐标必须在long long范围内. Input 第一行一个整数S(1<=S< ...

  8. EOJ Monthly 2018.11 猜价格 (模拟)

    分三种情况: 1.k=1.此时每次都说反话,反着二分即可. 2.1<k <= n.那么在前n次问答中一定会出现一次错误,通过不断输出1找出那个错误发生的位置(若回答是>那这就是错误) ...

  9. EOJ Monthly 2018.2

    A. 坑爹的售票机 题意 用\(1,5,10,25,50,100\)的纸币买\(n\)张单价为\(p\)的船票,且一次性最多买\(k\)张,求钱数恰好时最少需要多少张纸币. Hard: \(n,k,p ...

随机推荐

  1. Android UI开发第二十四篇——Action Bar

    Action bar是一个标识应用程序和用户位置的窗口功能,并且给用户提供操作和导航模式.在大多数的情况下,当你需要突出展现用户行为或全局导航的activity中使用action bar,因为acti ...

  2. 51nod 1873 高精度计算

    JAVA BigDecimal import java.util.*; import java.math.*; public class Main { public static void main( ...

  3. 51Nod 1087 1 10 100 1000 | 数学

    Input示例 3 1 2 3 Output示例 1 1 0 #include "bits/stdc++.h" using namespace std; #define LL lo ...

  4. LightOJ 1009 二分图染色+BFS/种类并查集

    题意:有两个阵营的人,他们互相敌对,给出互相敌对的人,问同个阵营的人最多有多少个. 思路:可以使用种类并查集写.也可以使用使用二分图染色的写法,由于给定的点并不是连续的,所以排序离散化一下,再进行BF ...

  5. LightOJ 1140 计数/数位DP 入门

    题意: 给出a,b求区间a,b内写下过多少个零 题解:计数问题一般都会牵扯到数位DP,DP我写的少,这道当作入门了,DFS写法有固定的模板可套用 dp[p][count] 代表在p位 且前面出现过co ...

  6. 奇偶排序Odd-even sort

    又一个比较性质的排序,基本思路是奇数列排一趟序,偶数列排一趟序,再奇数排,再偶数排,直到全部有序 举例吧, 待排数组[6 2 4 1 5 9] 第一次比较奇数列,奇数列与它的邻居偶数列比较,如6和2比 ...

  7. [BZOJ1177][BZOJ1178][BZOJ1179]APIO2009解题报告

    抱着好奇心态去开始做APIO的往年试题感受一下难度 Oil Description 采油区域 Siruseri政府决定将石油资源丰富的Navalur省的土地拍卖给私人承包商以建立油井.被拍卖的整块土地 ...

  8. 【BZOJ】2705: [SDOI2012]Longge的问题

    [题意]给定n,求∑gcd(i,n),(1<=i<=n),n<=2^32 [算法]数论(欧拉函数,gcd) [题解]批量求gcd的题目常常可以反过来枚举gcd的值. 记f(g)为gc ...

  9. 【51NOD-0】1019 逆序数

    [算法]离散化+树状数组(求逆序对) [题解]经典,原理是统计在i之前插入的且值≤i的个数,然后答案就是i-getsum(i) #include<cstdio> #include<a ...

  10. 【BZOJ】1588: [HNOI2002]营业额统计

    [算法]平衡树(treap)||双向链表 [题解]treap知识见数据结构. #include<cstdio> #include<algorithm> #include< ...