Phone Call

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others)

Problem Description
There are n houses in Bytetown, labeled by 1,2,...,n. In each house, there is a person living here. Little Q lives in house 1. There are n−1 bidirectional streets connecting these houses, forming a tree structure. In this problem, S(u,v) denotes the house set containing all the houses on the shortest path from house u to house v.

The Bytetown's phone line network consists of m different lines. The i-th line can be expressed as 5 integers ai,bi,ci,di,wi, which means for every two different houses u and v from set S(ai,bi)∪S(ci,di), u and v can have a phone call costing wi dollars.


Picture from Wikimedia Commons

Little Q is now planning to hold a big party in his house, so he wants to make as many as possible people known. Everyone known the message can make several phone calls to others to spread the message, but nobody can leave his house.

Please write a program to figure out the maximum number of people that can join the party and the minimum total cost to reach that maximum number. Little Q should be counted in the answer.

 
Input
The first line of the input contains an integer T(1≤T≤15), denoting the number of test cases.

In each test case, there are 2 integers n,m(1≤n,m≤100000) in the first line, denoting the number of houses and phone lines.

For the next n−1 lines, each line contains two integers u and v, denoting a bidirectional edge between node u and v.

For the next m lines, each line contains 5 integers ai,bi,ci,di,wi(1≤ai,bi,ci,di≤n,1≤wi≤109), denoting a phone line.

 
Output
For each test case, print a single line containing two integers, denoting the maximum number of people that can join the party and the minimum total cost to reach that maximum number.
 
Sample Input
1
5 2
1 2
1 3
2 4
2 5
1 3 2 4 100
2 2 4 2 10
 
Sample Output
4 210

Hint

Step 1 : 1 make a phone call to 2 using line 1, the cost is 100.
Step 2 : 1 make a phone call to 3 using line 1, the cost is 100.
Step 3 : 2 make a phone call to 4 using line 2, the cost is 10.

 

题解:

  将所有线路按代价从小到大排序,对于每条线路(a,b,c,d),首先把a到b路径上的点都合并到LCA,再把c到d路径上的点都合并到LCA,最后再把两个LCA合并即可。

  设f​i​​表示i点往上深度最大的一个可能不是和 i 在同一个连通块的祖先,每次沿着f跳即可。用路径压缩的并查集维护这个f即可得到优秀的复杂度。

  时间复杂度O(mlogm)。

#include <bits/stdc++.h>

inline long long read(){long long x=,f=;char ch=getchar();while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}return x*f;}

using namespace std;

typedef long long LL;

const int N = 2e5 + , inf = 1e9;

vector<int > G[N];
struct ss{int a,b,c,d,cost;}Q[N];
int cmp(ss s1,ss s2) {return s1.cost < s2.cost;}
int sz[N],dep[N],fa[N],son[N],indexS,top[N],pos[N],ff[N],f[N];
void dfs(int u) {
int k = ;sz[u] = ;dep[u] = dep[f[u]] + ;
for(auto to : G[u]) {
if(to == f[u]) continue;
f[to] = u;
dfs(to);
sz[u] += sz[to];
if(sz[to] > sz[k]) k = to;
}
if(k) son[u] = k;
}
void dfs(int u,int chain) {
int k = ;pos[u] = ++indexS;
top[u] = chain;
if(son[u])
dfs(son[u],chain);
for(auto to : G[u]) {
if(dep[to] > dep[u] && son[u] != to)
dfs(to,to);
}
}
int LCA(int x,int y) {
while(top[x] != top[y]) {
if(dep[top[x]] < dep[top[y]]) swap(x,y);
x = f[top[x]];
}
if(dep[x] > dep[y]) swap(x,y);
return x;
}
LL COST[N],CNT[N];
inline int finds2(int x) {return x == fa[x] ? x:fa[x] = finds2(fa[x]);}
inline int finds(int x) {return x == ff[x] ? x:ff[x] = finds(ff[x]);}
inline void merges(int x,int y,int c) {
int fx = finds2(x);
int fy = finds2(y);
if(dep[fx] < dep[fy]) swap(fx,fy);
if(fx == fy) return;
COST[fy] += COST[fx] + c;
CNT[fy] += CNT[fx];
fa[fx] = fy;
}
inline void go(int x,int zu,int c) {
while() {
x = finds(x);
if(dep[x] <= dep[zu]) return ;
merges(x,f[x],c);
ff[x] = f[x];
}
}
int n,m,T;
void init() {
for(int i = ; i <= n; ++i) G[i].clear(),top[i] = ,son[i] = ,dep[i] = ,fa[i] = ,pos[i] = ;
indexS = ;
}
int main() {
scanf("%d",&T);
while(T--) {
scanf("%d%d",&n,&m);
init();
for(int i = ; i < n; ++i){
int u,v;
scanf("%d%d",&u,&v);
G[u].push_back(v);
G[v].push_back(u);
}
dfs();
dfs(,);
for(int i = ; i <= n; ++i) fa[i] = ff[i] = i,CNT[i] = ,COST[i] = ;
for(int i = ; i <= m; ++i)
scanf("%d%d%d%d%d",&Q[i].a,&Q[i].b,&Q[i].c,&Q[i].d,&Q[i].cost);
sort(Q+,Q+m+,cmp);
for(int i = ; i <= m; ++i) {
int lc = LCA(Q[i].a,Q[i].b);
int lb = LCA(Q[i].c,Q[i].d);
go(Q[i].a,lc,Q[i].cost);
go(Q[i].b,lc,Q[i].cost);
go(Q[i].c,lb,Q[i].cost);
go(Q[i].d,lb,Q[i].cost);
merges(lc,lb,Q[i].cost);
//cout<<lc<<" "<<lb<<endl;
}
printf("%lld %lld\n",CNT[finds2()],COST[finds2()]);
}
return ;
}

HDU 6074 Phone Call LCA + 并查集的更多相关文章

  1. Codevs 3287 货车运输 2013年NOIP全国联赛提高组(带权LCA+并查集+最大生成树)

    3287 货车运输 2013年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 传送门 题目描述 Description A 国有 n 座 ...

  2. 【CodeForces】827 D. Best Edge Weight 最小生成树+倍增LCA+并查集

    [题目]D. Best Edge Weight [题意]给定n个点m条边的带边权无向连通图,对每条边求最大边权,满足其他边权不变的前提下图的任意最小生成树都经过它.n,m<=2*10^5,1&l ...

  3. HDU 5458 Stability(双连通分量+LCA+并查集+树状数组)(2015 ACM/ICPC Asia Regional Shenyang Online)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5458 Problem Description Given an undirected connecte ...

  4. Hdu 5458 Stability (LCA + 并查集 + 树状数组 + 缩点)

    题目链接: Hdu 5458 Stability 题目描述: 给出一个还有环和重边的图G,对图G有两种操作: 1 u v, 删除u与v之间的一天边 (保证这个边一定存在) 2 u v, 查询u到v的路 ...

  5. hdu 2874 Connections between cities (并查集+LCA)

    Connections between cities Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (J ...

  6. [bzoj3123][sdoi2013森林] (树上主席树+lca+并查集启发式合并+暴力重构森林)

    Description Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M,T,分别表示节点数.初始边数.操作数 ...

  7. 【BZOJ-3910】火车 倍增LCA + 并查集

    3910: 火车 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 262  Solved: 90[Submit][Status][Discuss] De ...

  8. HDU HDU1558 Segment set(并查集+判断线段相交)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1558 解题报告:首先如果两条线段有交点的话,这两条线段在一个集合内,如果a跟b在一个集合内,b跟c在一 ...

  9. hdu 1257 小希的迷宫 并查集

    小希的迷宫 Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=1272 D ...

随机推荐

  1. bzoj 1137 [POI2009]Wsp 岛屿

    题目大意 Byteotia岛屿是一个凸多边形.城市全都在海岸上.按顺时针编号1到n.任意两个城市之间都有一条笔直的道路相连.道路相交处可以自由穿行.有一些道路被游击队控制了,不能走,但是可以经过这条道 ...

  2. 【CF559C】 Gerald and Giant Chess(计数,方案数DP,数论)

    题意:给出一个棋盘为h*w,现在要从(1,1)到(h,w),其中有n个黑点不能走,问有多少种可能从左上到右下 (1 ≤ h, w ≤ 105, 1 ≤ n ≤ 2000),答案模10^9+7 思路:从 ...

  3. 标准C程序设计七---111

    Linux应用             编程深入            语言编程 标准C程序设计七---经典C11程序设计    以下内容为阅读:    <标准C程序设计>(第7版) 作者 ...

  4. HTTP PUT方法和POST方法的区别

    这两个方法看起来都是讲一个资源附加到服务器端的请求,但其实是不一样的.一些狭窄的意见认为,POST方法用来创建资源,而PUT方法则用来更新资源.这个说法本身没有问题,但是并没有从根本上解释了二者的区别 ...

  5. npm-debug.log文件出现原因

    项目主目录下总是会出现这个文件,而且不止一个,原因是npm i 的时候,如果报错,就会增加一个此文件来显示报错信息,npm install的时候则不会出现.

  6. inotify+rsync的初步配置

    inotify的简单配置  Linux内核从2.6.13开始,引入了inotify机制.通过intofity机制,能够对文件系统的变化进行监控,如对文件进行创建.删除.修改等操作,可以及时通知应用程序 ...

  7. 2002-2003 ACM-ICPC Northeastern European Regional Contest (NEERC 02)

    B Bricks 计算几何乱搞 题意: 给你个立方体,问你能不能放进一个管道里面. 题解: 这是一道非常迷的题,其问题在于,你可以不正着放下去,你需要斜着放.此时你需要枚举你旋转的角度,来判断是否可行 ...

  8. 第2章 Spring Boot 文档

    Spring Boot 文档 本节简要介绍了Spring Boot文档,是整个文档的参考指南. 您可以完整阅读本参考指南,或者如果您不感兴趣的话可以跳过该部分. 1. 关于文档 Spring Boot ...

  9. 弹出层layer演示 以及在编写弹出层时遇到的错误

    实现的功能: 首先第一步 在官方下载layer的文件.layUI官网:http://layer.layui.com/     http://layer.layui.com/ layer文件的下载步骤如 ...

  10. Kalendae使用总结

    2019-03-06 16:50:18 git官方教程:https://github.com/Twipped/Kalendae js.css:https://pan.baidu.com/s/1Ye-d ...