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. 启动hbase输出ignoring option PermSize=128m; support was removed in 8.0告警信息

    ./start-hbase.sh starting master, logging to /home/hadoop/hbase-1.2.4/bin/../logs/hbase-hadoop-maste ...

  2. intellj idea点击导航栏打开的一个类,怎么才能定位到类的目录

  3. 【spoj1182/usaco-Cow Queueing, 2003 Dec-二进制编号】数位dp

    题意:定义新的排序:先按一个数中二进制中1的个数从小到大排序,如果1的个数相同则按数的大小从小到大排序.问[A,B]之间有第K大的数是哪个.-2^31<=A,B<=2^31(A,B必定同正 ...

  4. 【BZOJ】1702: [Usaco2007 Mar]Gold Balanced Lineup 平衡的队列

    [题意]给定n头牛,k个特色,给出每头牛拥有哪些特色的二进制对应数字,[i,j]平衡当且仅当第i~j头牛的所有特色数量都相等,求最长区间长度. [算法]平衡树+数学转化 [题解]统计前缀和sum[i] ...

  5. 【BZOJ】2982 combination

    [算法]组合数取模——lucas定理 #include<cstdio> #include<algorithm> #include<cstring> using na ...

  6. JQuery-Ajax后台提交数据与获取数据 Java代码

    function jqajax(){ var urlName = $("#urlName").val(); var urla = $("#url").val() ...

  7. I题 hdu 1234 开门人和关门人

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1234 开门人和关门人 Time Limit: 2000/1000 MS (Java/Others)   ...

  8. perl6 拖库脚本

    #注入点: #https://fei.sg/shop/products.php?action=content&id=-23 #check mysql column_name of the sq ...

  9. C++学习之路(四):线程安全的单例模式

    (一)简单介绍 单例模式分为两种类型:懒汉模式和饿汉模式. 懒汉模式:在实际类对象被调用时才会产生一个新的类实例,并在之后返回这个实例.多线程环境下,多线程可能会同时调用接口函数创建新的实例,为了防止 ...

  10. ftrace 的使用【转】

    转自:http://blog.csdn.net/wang6077160/article/details/7814279 ftrace 的使用 ftrace 在内核态工作,用户通过 debugfs 接口 ...