博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HDU 6074 - Phone Call | 2017 Multi-University Training Contest 4
阅读量:6229 次
发布时间:2019-06-21

本文共 3220 字,大约阅读时间需要 10 分钟。

看标程的代码这么短,看我的....

难道是静态LCA模板太长了? 

/*HDU 6074 - Phone Call [ LCA,并查集 ]  |  2017 Multi-University Training Contest 4题意:	给一棵树,定义集合S(u,v)为u到v路径上所有的点	给出 m 个 
,意思为集合里面的点互相距离为 w 求 1 能到的所有点和该生成树的最小权值分析: 将所有线路按代价从小到大排序,对于每条线路(a,b,c,d) 分别把S(a,b)和S(c,d)合并到 LCA,最后再把两个 LCA 合并即可 再用f(i)表示i向上第一个与i不在同一个连通块的点, 就可用并查集压缩路径*/#include
using namespace std;#define LL long longconst int N = 100005;const int Q = 200005;vector
G[N];namespace LCA{ struct Query { int v, q; }; vector
query[N]; int ans[Q], f[N], vis[N]; int sf(int x) { return x == f[x] ? x : f[x] = sf(f[x]); } void init() { memset(ans, -1, sizeof(ans)); for (int i = 0; i < N; i++) { vis[i] = 0; f[i] = i; query[i].clear(); } } void adq(int u, int v, int id) { query[u].push_back(Query{v, id}); query[v].push_back(Query{u, id}); } void LCA(int u) { f[u] = u; vis[u] = 1; for (auto& x : query[u]) { if (vis[x.v] && ans[x.q] == -1) ans[x.q] = sf(x.v); } for (auto& v : G[u]) { if (vis[v]) continue; LCA(v); f[v] = u; } }}int pre[N];void dfs(int u, int fa) { pre[u] = fa; for (auto v : G[u]) { if (v == fa) continue; dfs(v, u); }}int f[N], num[N];LL res[N];int sf(int x){ return x == f[x] ? x : f[x] = sf(f[x]);}int same[N];int Same(int x) { return x == same[x] ? x : same[x] = Same(same[x]);}int w;void join(int a, int b){ a = sf(a), b = sf(b); if (a == b) return; f[b] = a; num[a] += num[b]; res[a] += res[b] + w;}struct Node { int a1, b1, a2, b2, w; int c1, c2;}e[N];bool cmp(Node a, Node b) { return a.w < b.w;}void solve(int a, int fa) { while (Same(a) != Same(fa)) { a = Same(a); join(pre[a], a); same[a] = pre[a]; }}int t, n, m;int main() { scanf("%d", &t); while (t--) { for (int i = 0; i < N; i++) G[i].clear(); LCA::init(); scanf("%d%d", &n, &m); for (int i = 1; i < n; i++) { int u, v; scanf("%d%d", &u, &v); G[u].push_back(v); G[v].push_back(u); } int Q = 0; for (int i = 1; i <= m; i++) { scanf("%d%d%d%d%d", &e[i].a1, &e[i].b1, &e[i].a2, &e[i].b2, &e[i].w); e[i].c1 = ++Q; LCA::adq(e[i].a1, e[i].b1, Q); e[i].c2 = ++Q; LCA::adq(e[i].a2, e[i].b2, Q); } LCA::LCA(1); for (int i = 1; i <= m; i++) { e[i].c1 = LCA::ans[e[i].c1]; e[i].c2 = LCA::ans[e[i].c2]; } dfs(1, 1); sort(e+1, e+m+1, cmp); for (int i = 1; i <= n; i++) { f[i] = same[i] = i; num[i] = 1; res[i] = 0; } for (int i = 1; i <= m; i++) { w = e[i].w; solve(e[i].a1, e[i].c1); solve(e[i].b1, e[i].c1); solve(e[i].a2, e[i].c2); solve(e[i].b2, e[i].c2); join(e[i].c1, e[i].c2); } printf("%d %lld\n", num[sf(1)], res[sf(1)]); }}

  

转载于:https://www.cnblogs.com/nicetomeetu/p/7301983.html

你可能感兴趣的文章
如何搭建一个独立博客——简明Github Pages与Hexo教程
查看>>
OC中Category的注意点
查看>>
OC中的布局-九宫格
查看>>
JAVA网络编程:计算机原理学习
查看>>
ARouter解析三:URL跳转本地页面源码分析
查看>>
git 常用操作
查看>>
iReport 中创建JavaBeanDataSource,用java类提供数据源给iReport
查看>>
大数据时代下的生活
查看>>
spring定时任务(方便轻巧)
查看>>
iOS的主要框架介绍
查看>>
spring源码阅读笔记(一)
查看>>
Selenium的简单安装和使用
查看>>
ios 滤镜
查看>>
linux系统学习第七天-<<工程师技术>>
查看>>
android中利用socket上传文件
查看>>
使用scrapy的定制爬虫-第二章-概
查看>>
【转】常见Java面试题
查看>>
数据库无法创建函数
查看>>
Shell字符串比较
查看>>
python3中二维List数据的三种处理方法及比较
查看>>