您的位置:首页 > 其它

hdu-3938-Portal-并查集

2016-07-11 15:45 344 查看
http://acm.hdu.edu.cn/showproblem.php?pid=3938

简单的讲就是,给你一张无向图,求有多少对点之间的路径花费小于L

这里路径花费:u-v 两点之间的多条路径中的最长的边最小值,一条路径中最长的边为其花费,若有多条取最长边最短的一条边。

数据规模:

There are multiple test cases. The first line of input contains three integer N, M and Q (1 < N ≤ 10,000, 0 < M ≤ 50,000, 0 < Q ≤ 10,000). N is the number of points, M is the number of edges and Q is the number of queries. Each of the next M lines contains three integers a, b, and c (1 ≤ a, b ≤ N, 0 ≤ c ≤ 10^8) describing an edge connecting the point a and b with cost c. Each of the following Q lines contain a single integer L (0 ≤ L ≤ 10^8).


可以知道 对于长度为L的询问,可以利用前面的结果更新答案,所以离线处理询问。

对q个询问长度L升序排序,边权升序排序;

遍历L,对比L小的边,取出边对应的uv,看是否联通,如果联通跳过,否则便合并两个集合,而此时导致,与u联通的点集 与  【与v连通的点集】 联通了, 因此新增的点对数,为两者乘积,不断更新答案,o(m)复杂度

#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <iostream>
using namespace std;

const double pi=acos(-1.0);
double eps=0.000001;

int fa[11234];
int num[11234]; //记录该树下有多少儿子
int find(int x)
{
if (fa[x]==x)
return x;
else return fa[x]=find(fa[x]);
}
struct node
{
int x,y,z;
node() {}
};

node tm[51234];
bool cmp1(node a,node b)
{
return a.z<b.z;
}
struct que
{
int id,x;
};
que qus[11234];
bool cmp2(que a,que b)
{
return a.x<b.x;
}
long long ans[11234];
int main()
{
int n,m,q;
while(scanf("%d%d%d",&n,&m,&q)!=EOF)
{
int x,y,z;
for (int i=1; i<=m; i++)
{
scanf("%d %d %d",&x,&y,&z);
tm[i].x=x;
tm[i].y=y;
tm[i].z=z;
}
sort(tm+1,tm+1+m,cmp1);
for (int i=1; i<=q; i++)
{
scanf("%d",&qus[i].x);
qus[i].id=i;
}
sort(qus+1,qus+1+q,cmp2);
for (int i=1; i<=n; i++) fa[i]=i,num[i]=1;
long long sum=0;
int j=1;
for (int i=1; i<=q; i++)
{

for (; j<=m; j++)
{
if (tm[j].z>qus[i].x) break;
int x=tm[j].x;
int y=tm[j].y;
int fx=find(x);
int fy=find(y);
if (fx!=fy)
{
fa[fx]=fy;
sum+=num[fx]*num[fy];
num[fy]+=num[fx];
}
}
ans[qus[i].id]=sum;
}
for (int i=1; i<=q; i++)
{
printf("%lld\n",ans[i]);
}
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: