[HDU - 5441]Travel
Posted vikyanite
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[HDU - 5441]Travel相关的知识,希望对你有一定的参考价值。
大意:告诉你有n个点 m个边的无向图
然后问有多少点对 他们的路径上节点之间的距离都少于 x
思路:
并查集
离线处理。将边权值按从小到大排序,查询标号后按照从小到大排序。对于每次查询,依次将比当前查询值小的边加入并查集。
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; int t; int n,m,q; struct path int starts; int ends; int weight; bool operator <(const path &x)const return weight<x.weight; P[100000 + 5]; struct input int id; int limit; bool operator <(const input &x)const return limit < x.limit; L[100000 + 5]; long long ans[5000 + 5]; int father[20000 + 5]; int cnt[20000 + 5]; int Find(int x) return father[x] == x ? x : father[x] = Find(father[x]); void init() for (int j = 1; j <= n; j++) father[j] = j; cnt[j] = 1; memset(ans,0,sizeof(ans)); int main() scanf("%d", &t); while (t--) scanf("%d%d%d", &n, &m, &q); for (int i = 0; i < m; i++) scanf("%d %d %d", &P[i].starts, &P[i].ends, &P[i].weight); sort(P, P + m); for (int i = 0; i < q; i++) L[i].id = i; scanf("%d", &L[i].limit); sort(L, L + q); init(); int cur = 0; long long sum = 0; for (int i = 0; i < q; i++) while (cur < m && L[i].limit >= P[cur].weight) int fstarts = Find(P[cur].starts); int fends = Find(P[cur].ends); if(fstarts != fends) sum += cnt[fstarts] * cnt[fends]; //将总联通块合并,再将合并之前的已有的减去,得到的算式化简得 father[fends] = fstarts; cnt[fstarts] += cnt[fends]; cur++; ans[L[i].id] = sum; for(int i = 0; i < q; i++) printf("%lld\n", 2 * ans[i]); return 0;
以上是关于[HDU - 5441]Travel的主要内容,如果未能解决你的问题,请参考以下文章
Travel(HDU 5441 2015长春区域赛 带权并查集)
2015 ACM/ICPC Asia Regional Changchun Online HDU - 5441 (离线+并查集)