HDU - 3938(Portal)并查集+离线

HDU - 3938

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

先说题目意思吧 真TM想踹题白白浪费一小时就搜各个博客就为了想知道题目是啥意思 好吧 它真的是一道好题

给出n,m,q; n是有多少个点  m是有多少遍 q是有多少询问

在给出当前的能量的情况下!

扫描二维码关注公众号,回复: 4195545 查看本文章

就是求A集合  和 B集合之间 他们之间相互连接!相互连接起来可以有多少个点对(X,Y)是小于当前的能量

先把边从小到大排个序,怎么那么像最小生成树。。。。。啊啊啊啊 其实就是就有点像变形最小生成树

离线离线就是输入完在处理,咋们平时不都是边输入边merge吗因为没有权值啊 这题有啊

举个栗子

排完序对吧 1 1 2 5 6 6 7 8 9 10

排完序

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

因为m条边啊所以肯定不能大于它呢 他们连接花费的东西当然也不能大于当前的能量啊

看下这个地方

当前值为1 时候                      2和7一堆了   此刻点对有1

当前值为1 。。。。。。。没改变

当前值为2  又增加了一个点对了  58  此刻点对有2  扎堆的有 (27)    (58)

当前值为5!!

6  8== 3对吧 可是此刻 5和8在一起了  6再进去就是加2 对吧  所以 现在加2  点对为  1 + 1 + 2 =4

现在一堆的有 27                         856

6 4 ==5 进去了    所以!此刻 4 和568扎堆了 那么点对再加3    点对为1+1+2+3=7

现在一堆的有 27                         4856

2 1 ==== 5 进去了 所以!1和27扎堆了  那么点对再加2   点对为1 + 1 + 2 + 3 + 2 = 9

现在一堆的有 127                         4856

8 10 ====5 进去了 所以! 10 和4856扎堆了 那么点对为1 + 1 + 2 + 3 + 2 + 4 = 13

现在你懂什么意思了把?  别管这句话真的

T in a path between point V and point U is the length of the longest edge in the path 害老子想了一晚上生气

a 集合和b集合联合在一起 sum = rank[a] * rank[b]   你想想 27   34   他们点对是不是 1 + 1 + 4  对吧  rank[a] = 2;

rank[b] = 2;   是吧?  所以就是4 over! 再见!

代码!

#include<cstdio>
#include<algorithm>
using namespace std;
int n, m, q;
const int maxn = 1e4+10;
int pre[maxn],ranks[maxn]; 
struct node
{
	int x , y , val; 
	bool operator < (const node &a)const{
     	return val < a.val;
	}
}edge[maxn * 5];
struct GG
{
	int id,q,ans;
}query[maxn];
bool cmp1(GG a, GG b){
	return a.q < b.q;
}
bool cmp2(GG a, GG b){
	return a.id < b.id;
}
int find(int x)
{
	if(pre[x] == x)
		return x;
	else
		return pre[x] = find(pre[x]);	
}
int merge(int x,int y)
{
	int fx = find(x);
	int fy = find(y);
	if(fx != fy)
	{
		pre[fy] = fx;
		int temp = ranks[fx];
		ranks[fx] = ranks[fx] + ranks[fy];
		return temp * ranks[fy];
	}
	return 0;	
} 
int main()
{
	while(~scanf("%d %d %d",&n,&m,&q))
	{
		for(int i = 1 ; i <= m; i++)
			scanf("%d %d %d",&edge[i].x, &edge[i].y, &edge[i].val);
		for(int i = 1; i <= q; i++)
		{
			scanf("%d",&query[i].q);
			query[i].id = i;
			query[i].ans = 0;
		}	
		sort(edge + 1, edge + 1 + m);
		sort(query + 1,query + 1 + q, cmp1);	
		for(int i = 1; i <= m; i ++)
			printf("%d %d %d \n",edge[i].x ,edge[i].y, edge[i].val);
		for(int i = 1; i <= n; i++)
		{
			pre[i] = i;
			ranks[i] = 1;
		}
		int cnt = 1;
		for(int i = 1; i <= q; i ++)
		{
			query[i].ans += query[i - 1].ans;
			while(cnt <= m && edge[cnt].val <= query[i].q) //因为m条边啊所以肯定不能大于它呢 他们连接花费的东西当然也不能大于当前的能量啊
			{
				query[i].ans += merge(edge[cnt].x, edge[cnt].y);
				cnt++;
			} 
		}
		sort(query + 1,query + 1 + q, cmp2);
		for(int i = 1; i <= q; i ++)
			printf("%d\n",query[i].ans);
	}
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/galesaur_wcy/article/details/84145697
今日推荐