Phone Call

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others)
Total Submission(s): 156    Accepted Submission(s): 67

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.

【题意】给你一棵树,然后给你M哥条件,每次给出a,b,c,d,cost,表示从a-->b,c-->d的路径中的点,可以互相到达,花费是cost,到达具有传递性 ,现在问你从1节点最多可以到达哪些节点,最小花费是多少。
【分析】将点集合挨个合并算最小花费,这个过程类似最小生成树。考虑将花费从小到大排序,设up[i]表示i点往上深度最小的一个可能不是和i在同一个
  连通块的祖先,每次沿着up[i]跳即可。用路径压缩的并查集维护这个ff即可得到优秀的复杂度。

#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define met(a,b) memset(a,b,sizeof a)
#define pb push_back
#define mp make_pair
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int N = 1e5+;;
const int M = ;
const int mod = 1e9+;
const double pi= acos(-1.0);
typedef pair<int,int>pii;
int n,m,T;
int parent[N],up[N],cnt[N];
int dep[N],fa[N][];
ll w[N];
vector<int>edg[N];
struct man{
int a,b,c,d;
ll cost;
bool operator < (const man &e)const {
return cost<e.cost;
}
}q[N];
int findFa(int x){
return parent[x]==x?x:parent[x]=findFa(parent[x]);
}
int findUp(int x){
return up[x]==x?x:up[x]=findUp(up[x]);
}
void dfs(int u,int f){
fa[u][]=f;
for(int i=;i<;i++){
fa[u][i]=fa[fa[u][i-]][i-];
}
for(int v : edg[u]){
if(v==f)continue;
dep[v]=dep[u]+;
dfs(v,u);
}
}
int LCA(int u,int v){
int U=u,V=v;
if(dep[u]<dep[v])swap(u,v);
for(int i=;i>=;i--){
if(dep[fa[u][i]]>=dep[v]){
u=fa[u][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 Union(int x,int y,ll cost){
x=findFa(x);y=findFa(y);
if(x==y)return;
parent[x]=y;
cnt[y]+=cnt[x];
w[y]+=w[x]+cost;
}
void merge(int u,int v,ll cost){
while(){
u=findUp(u);
if(dep[u]<=dep[v])return;
Union(u,fa[u][],cost);
up[u]=fa[u][];
}
}
void solve(man s){
int lca=LCA(s.a,s.b);
merge(s.a,lca,s.cost);
merge(s.b,lca,s.cost);
lca=LCA(s.c,s.d);
merge(s.c,lca,s.cost);
merge(s.d,lca,s.cost);
Union(s.a,s.c,s.cost);
}
int main(){
scanf("%d",&T);
while(T--){
scanf("%d%d",&n,&m);met(fa,);
for(int i=;i<=n;i++)parent[i]=up[i]=i,cnt[i]=,w[i]=,edg[i].clear();
for(int i=,u,v;i<n;i++){
scanf("%d%d",&u,&v);
edg[u].pb(v);edg[v].pb(u);
}
for(int i=;i<m;i++){
scanf("%d%d%d%d%lld",&q[i].a,&q[i].b,&q[i].c,&q[i].d,&q[i].cost);
}
sort(q,q+m);
dep[]=;dfs(,);
for(int i=;i<m;i++)solve(q[i]);
printf("%d %lld\n",cnt[findFa()],w[findFa()]);
}
}

HDU6074 Phone Call (并查集 LCA)的更多相关文章

  1. hdu6074[并查集+LCA+思维] 2017多校4

    看了标答感觉思路清晰了许多,用并查集来维护全联通块的点数和边权和. 用另一个up[]数组(也是并查集)来保证每条边不会被重复附权值,这样我们只要将询问按权值从小到大排序,一定能的到最小的边权和与联通块 ...

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

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

  3. Gym 100814C Connecting Graph 并查集+LCA

    Description standard input/output Statements Alex is known to be very clever, but Walter does not be ...

  4. Network-POJ3694并查集+LCA

    Network Time Limit: 5000MS   Memory Limit: 65536K       Description A network administrator manages ...

  5. [并查集+LCA USACO18OPEN ] Disruption

    https://www.luogu.org/problemnew/show/P4374 一看这道题就是一个妙题,然后题解什么树链剖分...珂朵莉树... 还不如并查集来的实在!我们知道并查集本来就是路 ...

  6. Mobile Phone Network CodeForces - 1023F(并查集lca+修改环)

    题意: 就是有几个点,你掌控了几条路,你的商业对手也掌控了几条路,然后你想让游客都把你的所有路都走完,那么你就有钱了,但你又想挣的钱最多,真是的过分..哈哈 游客肯定要对比一下你的对手的路 看看那个便 ...

  7. 习题:过路费(kruskal+并查集+LCA)

    过路费  [问题描述]在某个遥远的国家里,有 n 个城市.编号为 1,2,3,…,n.这个国家的政府修 建了 m 条双向道路,每条道路连接着两个城市.政府规定从城市 S 到城市 T 需 要收取的过路费 ...

  8. BZOJ 4668 冷战(按秩合并并查集+LCA)

    4668: 冷战 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 627  Solved: 303[Submit][Status][Discuss] D ...

  9. [CSP-S模拟测试]:Dash Speed(线段树+并查集+LCA)

    题目描述 比特山是比特镇的飙车圣地.在比特山上一共有$n$个广场,编号依次为$1$到$n$,这些广场之间通过$n−1$条双向车道直接或间接地连接在一起,形成了一棵树的结构. 因为每条车道的修建时间以及 ...

随机推荐

  1. 省队集训Day1 睡觉困难综合征

    传送门:https://www.luogu.org/problem/show?pid=3613 [题解] 按二进制位分开,对于每一位,用“起床困难综合征”的方法贪心做. 写棵LCT,维护正反两种权值, ...

  2. 【转载】Lua中实现类的原理

    原文地址 http://wuzhiwei.net/lua_make_class/ 不错,将metatable讲的很透彻,我终于懂了. --------------------------------- ...

  3. pythonTensorFlow实现yolov3训练自己的目标检测探测自定义数据集

    1.数据集准备,使用label标注好自己的数据集. https://github.com/tzutalin/labelImg 打开连接直接下载数据标注工具, 2.具体的大师代码见下链接 https:/ ...

  4. hdu 1217 Arbitrage (spfa算法)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1217 题目大意:通过货币的转换,来判断是否获利,如果获利则输出Yes,否则输出No. 这里介绍一个ST ...

  5. 【Eclipse】Eclipse中修改项目的映射名称与端口

    1.正常部署(映射的名字为项目名字,端口为8080)

  6. AMD嵌入式G系列SoC协助优化Gizmo 2开发板

    http://www.gizmosphere.org/ AMD嵌入式G系列SoC协助优化Gizmo 2开发板 http://news.zol.com.cn/491/4910444.html

  7. C基础 读写锁中级剖析

    引言 读写锁 是为了 解决, 大量 ''读'' 和 少量 ''写'' 的业务而设计的. 读写锁有3个特征: 1.当读写锁是写加锁状态时,在这个锁被解锁之前,所有试图对这个锁加锁的线程都会被阻塞 2.当 ...

  8. 自动安装jar包到本地仓库

    参考博客:http://blog.csdn.net/m0_37797991/article/details/73394873

  9. gunicorn 启动无日志

    gunicorn -c gunicorn_info.py info:app 接手整理老项目,发现有个服务迁移后启动不了,也没报错信息 修改gunicorn_info.py里的daemon = not ...

  10. .net设置浏览器的文本模式

    这段时间做个项目,做的时候因为之前习惯了Google的调试方式,所以就一直在google上面调试,今天项目成员大家的部分要整合,就放到ie8下面测试,但是遇到一个问题,就是用ie打开之后文本模式一直是 ...