题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3938
题目大意为:求有多少个点对满足要求L>=min{T},这里的T指的是两个点之间联通的一条路径上的最长的边的长度,两个点之间有很多路径。
emm,最开始题目都没读懂。
然后参考了下面这位博主的做法:https://blog.csdn.net/sdj222555/article/details/7439187
先输入所有的边和L,对所有的L进行排序,对所有的边进行排序,都为从小到大,然后对每个L,将比其小的边权的边都并在一起,计算种类数即可。
AC代码:
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;
import java.util.Arrays;
//离线加并查集
//题目大意为:求有多少个点对满足要求L>=min{T},这里的T指的是两个点之间联通的一条路径上的最长的边的长度,两个点之间有很多路径。
//也就是求两点之间所有路径上最长边的最小值满足<=L
public class Main {
static int maxn=10005;
static int maxm=50005;
static int num[]=new int[maxn];//存储满足要求的点对数
static int fa[]=new int[maxn];
static class edge implements Comparable<edge>{
int u,v,cost;
public edge(int u, int v, int cost) {
super();
this.u = u;
this.v = v;
this.cost = cost;
}
@Override
public int compareTo(edge ed) {
return (this.cost-ed.cost);
}
}
static class P implements Comparable<P>{
int id,l;
@Override
public int compareTo(P p) {
return this.l-p.l;
}
public P(int id, int l) {
super();
this.id = id;
this.l = l;
}
}
static P p[]=new P[maxn];
static edge e[]=new edge[maxm];
static int find(int x){
return x==fa[x]?x:(fa[x]=find(fa[x]));
}
static StreamTokenizer st=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
static PrintWriter out=new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
public static void main(String[] args) throws IOException {
while(st.nextToken()!=StreamTokenizer.TT_EOF){
int n,m,q;
n=(int)st.nval;
m=nextInt();
q=nextInt();
int a,b,c;
for(int i=0;i<=n;i++){
fa[i]=i;
num[i]=1;
}
for(int i=0;i<m;i++){
a=nextInt();
b=nextInt();
c=nextInt();
e[i]=new edge(a,b,c);
}
Arrays.sort(e,0,m);
for(int i=0;i<q;i++){
int l=nextInt();
p[i]=new P(i,l);
}
Arrays.sort(p,0,q);
long ans=0;
int pos=0;
long goal[]=new long[q];
for(int i=0;i<q;i++){
while(pos<m&&e[pos].cost<=p[i].l){
ans+=merge(e[pos].u,e[pos].v);
pos++;
}
goal[p[i].id]=ans;
}
for(int i=0;i<q;i++){
out.println(goal[i]);
}
out.flush();
}
}
static long merge(int u, int v) {
int x=find(u);
int y=find(v);
if(x==y)
return 0;
int t=num[x]*num[y];
num[x]+=num[y];
num[y]=0;
fa[y]=x;
return t;
}
static int nextInt(){
try {
st.nextToken();
} catch (IOException e) {
e.printStackTrace();
}
return (int)st.nval;
}
}