codevs 1450 xth 的旅行

 时间限制: 1 s
 空间限制: 128000 KB
 题目等级 : 钻石 Diamond
 
 
题目描述 Description

毕业了,Xth很高兴,因为他要和他的 rabbit 去双人旅行了。他们来到了水城威尼
斯。众所周知(⊙﹏⊙b汗),这里的水路交通很发达,所以 xth 和 rabbit 只好坐
船穿梭于各个景点之间。但是要知道,rabbit 是会晕船的,看到她难受,xth 是会
心疼的。
已知城市中有n个景点,这些景点之间有m条双向水路,在每条水路上航行时
rabbit 都会有一个“晕船值”。旅行时,xth 会带着 rabbit 尽量选择晕船值小的路线
旅行。但是 rabbit 也是有一定忍耐限度度的,如果晕船值超过了她的忍耐度,xth
会果断决定放弃这条路线。
现在 xth 想进行若干次询问,给定 rabbit 的忍耐度,问还有多少对城市(x,y)间会存
在可行的旅行路线(如果(x,z)和(z, y)可行,则(x,y)可行,也就是说连通性是可传
递的)。

输入描述 Input Description

第 1 行三个正整数n、m、q,分别表示景点数量、水路数量和询问次数。
第 2 行到第m + 1行每行三个正整数x、y、w,表示x号景点和y号景点之间有一条
“晕船值”为w的双向水路。
第m + 2行至第m + q + 1行,每行一个正整数k,表示询问中给定的 rabbi忍耐度
为k。

输出描述 Output Description

共q行,对于每次询问做出回答。

样例输入 Sample Input

5 5 2

1 2 1

2 3 2

3 4 1

4 5 4

5 1 1

1

2

样例输出 Sample Output

4

10

数据范围及提示 Data Size & Hint

第一个询问:(1,2), (1,5), (2,5), (3,4)。其中(2,5)的具体走法为:2 − 1 − 5
第二个询问:(1,2), (1,3), (1,4), (1,5), (2,3), (2,4), (2,5), (3,4), (3,5), (4,5)。其中(4,5)
的具体走法为:4 − 3 − 2 − 1 − 5

对于20%的数据满足n ≤ 20,m ≤ 40,q ≤ 40;
对于40%的数据满足n ≤ 1000,m ≤ 2000,q ≤ 1000;
对于60%的数据满足n ≤ 3000,m ≤ 6000,q ≤ 200000;
对于100%的数据满足n ≤ 100000,m ≤ 200000,q ≤ 200000。其他数不超过10
9。

 

 

并查集离线水题

#include<bits/stdc++.h>
#define ll long long
#define maxn 200005
using namespace std;
struct lines{
	int u,v,w;
	bool operator <(const lines &U)const{
		return w<U.w;
	}
}l[maxn];
struct node{
	int a,num;
	bool operator <(const node &U)const{
		return a<U.a;
	}
}q[maxn];
int n,m,Q;
int siz[maxn],p[maxn];
ll now=0,ans[maxn];

int ff(int x){
	return p[x]==x?x:(p[x]=ff(p[x]));
}

inline void update(lines x){
	int fa=ff(x.u),fb=ff(x.v);
	if(fa!=fb){
		now+=siz[fa]*(ll)siz[fb];
		p[fa]=fb;
		siz[fb]+=siz[fa];
	}
}

inline void solve(){
	sort(q+1,q+Q+1);
	sort(l+1,l+m+1);
	
	int linenum=0;
	for(int i=1;i<=Q;i++){
		while(linenum<m&&l[linenum+1].w<=q[i].a){
			update(l[linenum+1]);
			linenum++;
		}
		ans[q[i].num]=now;
	}
}

int main(){
	scanf("%d%d%d",&n,&m,&Q);
	for(int i=1;i<=n;i++) siz[i]=1,p[i]=i;
	for(int i=1;i<=m;i++){
		scanf("%d%d%d",&l[i].u,&l[i].v,&l[i].w);
	}
	for(int i=1;i<=Q;i++){
		scanf("%d",&q[i].a);
		q[i].num=i;
	}
	
	solve();
	
	for(int i=1;i<=Q;i++) printf("%lld\n",ans[i]);
	return 0;
}

  

posted @ 2018-02-25 21:27  蒟蒻JHY  阅读(189)  评论(0编辑  收藏  举报