码迷,mamicode.com
首页 > 其他好文 > 详细

hdu3938 Portal

时间:2015-05-13 22:06:01      阅读:153      评论:0      收藏:0      [点我收藏+]

标签:并查集

Problem Description
ZLGG found a magic theory that the bigger banana the bigger banana peel .This important theory can help him make a portal in our universal. Unfortunately, making a pair of portals will cost min{T} energies. T in a path between point V and point U is the length of the longest edge in the path. There may be lots of paths between two points. Now ZLGG owned L energies and he want to know how many kind of path he could make.
 

Input
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).
 

Output
Output the answer to each query on a separate line.
 

Sample Input
10 10 10 7 2 1 6 8 3 4 5 8 5 8 2 2 8 9 6 4 5 2 1 5 8 10 5 7 3 7 7 8 8 10 6 1 5 9 1 8 2 7 6
 

Sample Output
36 13 1 13 36 1 36 2 16
13

题目要求a、b两点之间所有的路径中的最大边的最小值。

这题可以用并查集做,因为询问次数很多,所以要离线操作。设数组num[i],只记录i所在集合的总顶点数(一开始以为是记录边的,其实是记录顶点的),先对所有的边排序,从小到大,(其实可以看做是依次枚举最大边的最小值,因为如果这条线段的两端点不在一个集合,即两个集合的边不相连,那么这条线段就起到了桥梁的作用,也就是说任意两个集合的点相连都要通过这条边,因为之前两个集合的最大边的最小值都符合条件,那么如果这条线段也符合条件,就可以把两个集合的点都连起来),因为能量大的值一定包括能量小的路径,所以每次初始化的时候p[i].sum=p[i-1].sum;

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<map>
#include<string>
using namespace std;
int pre[10006],num[10006];
struct edge
{
	int from,to,len;
}e[50006];
struct node
{
	int id,num,sum;
}q[10006];

bool cmp1(edge a,edge b)
{
	int temp;
	if(a.len>b.len){
		temp=a.from;a.from=b.from;b.from=temp;
		temp=a.to;a.to=b.to;b.to=temp;
		return a.len<b.len;
	}
	return a.len<b.len;
}
bool cmp2(node a,node b)
{
	int temp;
	if(a.num>b.num){
		temp=a.id;a.id=b.id;b.id=temp;
		return a.num<b.num;
	}
	return a.num<b.num;
}
bool cmp3(node a,node b)
{
	int temp;
	if(a.id>b.id){
		temp=a.sum;a.sum=b.sum;b.sum=temp;
		return a.id<b.id;
	}
	return a.id<b.id;
}
int find(int x)
{
	int r=x,i,j=x;
	while(r!=pre[r])r=pre[r];
	while(j!=pre[j]){
		i=pre[j];
		pre[j]=r;
		j=i;
	}
	return r;
}

int main()
{
	int n,m,i,j,a,b,c,p,t1,t2,ans;
	while(scanf("%d%d%d",&n,&m,&p)!=EOF)
	{
		for(i=0;i<=n;i++){
			pre[i]=i;num[i]=1;
		}
		for(i=1;i<=m;i++){
			scanf("%d%d%d",&e[i].from,&e[i].to,&e[i].len);
		}
		sort(e+1,e+1+m,cmp1);
		for(i=1;i<=p;i++){
			scanf("%d",&q[i].num);
			q[i].id=i;
		}
		sort(q+1,q+p+1,cmp2);
		ans=1;
		q[0].sum=0;
		for(i=1;i<=p;i++){
			q[i].sum=q[i-1].sum;
			while(ans<=m && e[ans].len<=q[i].num){
			     t1=find(e[ans].from);t2=find(e[ans].to);
			     if(t1==t2){
     				ans++;continue;
     			 }
			     pre[t1]=t2;
			     q[i].sum+=num[t1]*num[t2];
			     num[t2]+=num[t1];
			     ans++;
			}
		}
		
		sort(q+1,q+1+p,cmp3);
		for(i=1;i<=p;i++){
			printf("%d\n",q[i].sum);
		}
	}
	return 0;
}


hdu3938 Portal

标签:并查集

原文地址:http://blog.csdn.net/kirito_acmer/article/details/45696693

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!