HDU 6074 Phone Call LCA + 并查集
Phone Call
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 524288/524288 K (Java/Others)
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.
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.
5 2
1 2
1 3
2 4
2 5
1 3 2 4 100
2 2 4 2 10
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合并即可。
设fi表示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 + 并查集的更多相关文章
- Codevs 3287 货车运输 2013年NOIP全国联赛提高组(带权LCA+并查集+最大生成树)
3287 货车运输 2013年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 传送门 题目描述 Description A 国有 n 座 ...
- 【CodeForces】827 D. Best Edge Weight 最小生成树+倍增LCA+并查集
[题目]D. Best Edge Weight [题意]给定n个点m条边的带边权无向连通图,对每条边求最大边权,满足其他边权不变的前提下图的任意最小生成树都经过它.n,m<=2*10^5,1&l ...
- 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 ...
- Hdu 5458 Stability (LCA + 并查集 + 树状数组 + 缩点)
题目链接: Hdu 5458 Stability 题目描述: 给出一个还有环和重边的图G,对图G有两种操作: 1 u v, 删除u与v之间的一天边 (保证这个边一定存在) 2 u v, 查询u到v的路 ...
- hdu 2874 Connections between cities (并查集+LCA)
Connections between cities Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (J ...
- [bzoj3123][sdoi2013森林] (树上主席树+lca+并查集启发式合并+暴力重构森林)
Description Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M,T,分别表示节点数.初始边数.操作数 ...
- 【BZOJ-3910】火车 倍增LCA + 并查集
3910: 火车 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 262 Solved: 90[Submit][Status][Discuss] De ...
- HDU HDU1558 Segment set(并查集+判断线段相交)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1558 解题报告:首先如果两条线段有交点的话,这两条线段在一个集合内,如果a跟b在一个集合内,b跟c在一 ...
- hdu 1257 小希的迷宫 并查集
小希的迷宫 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=1272 D ...
随机推荐
- 阶乘-递归-java
public class Main { public static void main(String[] args) { for (int i=0;i<11;i++){ System.out.p ...
- php validator classes
<?php /** * 验证类 */ class Validator { /* 函数名称:isNumber 简要描述:检查输入的是否为数字 输入:string 输出:boolean */ pub ...
- Git基础篇【转】
转自:https://i.cnblogs.com/EditPosts.aspx?opt=1 1.设置名字与邮箱 $ Git config –global user.name “YourName” $ ...
- Java通过开启线程池实现多线程
计算1..100 和1...200 的和,使用线程池开启两个线程 调用Executors类的newFixedThreadPool方法参数是线程池容纳的线程数量 这里是2 返回的对象是 Executo ...
- LeetCode OJ--Next Permutation *
求一个排列的下一个排列. 1,2,3 → 1,3,23,2,1 → 1,2,31,1,5 → 1,5,1 #include <iostream> #include <vector&g ...
- 使用sqlparse分析SQL语句,及自己写的SQL分析语句
备忘, 以后写的时候可以参考. #!/usr/bin/env python # -*- coding: utf-8 -*- import sqlparse import re sql = " ...
- AC日记——【模板】最近公共祖先(LCA)洛谷 P3379
题目描述 如题,给定一棵有根多叉树,请求出指定两个点直接最近的公共祖先. 输入输出格式 输入格式: 第一行包含三个正整数N.M.S,分别表示树的结点个数.询问的个数和树根结点的序号. 接下来N-1行每 ...
- BZOJ——1622: [Usaco2008 Open]Word Power 名字的能量
http://www.lydsy.com/JudgeOnline/problem.php?id=1622 Description 约翰想要计算他那N(1≤N≤1000)只奶牛的名字的能量.每只 ...
- [Bzoj4943][Noi2017]蚯蚓(hash)
4943: [Noi2017]蚯蚓 Time Limit: 50 Sec Memory Limit: 512 MBSubmit: 237 Solved: 110[Submit][Status][D ...
- ARC下循环引用的问题
最初 最近在开发应用时碰到使用ASIHttpRequest后在某些机器上发不出请求的问题,项目开启了ARC,代码是这样写的: @implement MainController - (void) fe ...