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. SharepPoint 2013安装体会

    SharePoint 2013出来了,一直没有找到合适的机器来安装.前天腾出来一台内存8G的机器,决定在Hyper-V上安装在一台虚机,然后装个Windows 2012,再装SharePoint 20 ...

  2. angular中关于文件引入

    var angular = require('angular'); module.exports = angular.module('app.mymodule2', []).controller('H ...

  3. 微信小程序踩坑之一【weui-wxss-master单选按钮图标修改思路】

    小程序原生所带的weui框架做小程序UI实在太方便了,但是他的一些细微变化也是让开发中碰到不少头疼的问题 一直以来单选多选的美化都是设计师重点表达的地方之一 而weui-wxss-master中的单选 ...

  4. Atcoder Grand Contest 024

    A 略 B 略 C 略 D(构造分形) 题意: 给出一个由n个点的组成的树,你可以加一些点形成一个更大的树.对于新树中的两个点i和j,如果以i为根的树与以j为根的树是同构的那么i和j颜色可以相同.问最 ...

  5. JVM加载的初始化类

    首先Throws(抛出)几个自己学习过程中一直疑惑的问题: 1.什么是类加载?什么时候进行类加载? 2.什么是类初始化?什么时候进行类初始化? 3.什么时候会为变量分配内存? 4.什么时候会为变量赋默 ...

  6. 迅雷中Peer连接信息中的状态解释(转)

    在标准 Peer-to-Peer(P2P 点对点网络)中,以"Flags"表示 Peer Status(Peer 状态).其中: D - 正从 Peer 下载(感兴趣:解阻塞)搜索 ...

  7. FastDFS 使用经验分享

    原文:http://www.ttlsa.com/fastdfs/fastdfs-experience-sharing/ 应用背景 文件被上传到FastDFS后Storage服务端将返回的文件索引(FI ...

  8. POJ2503字典树

    此代码原始出处:http://blog.csdn.net/cnyali/article/details/47367403 #include<stdio.h> #include<str ...

  9. procomm plus

    procomm plus这是查看串口数据的软件.

  10. 21. Spring Boot过滤器、监听器【从零开始学Spring Boot】

    转载:http://blog.csdn.net/linxingliang/article/details/52069490 上一篇文章已经对定义Servlet 的方法进行了说明,过滤器(Filter) ...