题意: 恶心的题意,看了好久也看不懂.
简单的讲就是,给你一张无向图,求有多少条路径使得路径上的花费小于L,这里路径上的花费是这样规定的,a、b两点之间的多条路径中的最长的边最小值!
和最小生成树的思想差不多。
#include<bits/stdc++.h>
#define m(a,b) memset(a,b,sizeof a)
using namespace std;
typedef long long ll;
const int N=10000+5,M=50000+5;
struct Graph{
int from,to,val;
friend bool operator<(const Graph &a,const Graph &b){return a.val<b.val;}
}e[M];
struct Query{
int pro,id;
friend bool operator<(const Query &a,const Query &b){return a.pro<b.pro;}
}q[N];
int f[N],cnt[N],fin[N];
int seek(int x){ return (x==f[x])?(x):(f[x]=seek(f[x]));}
/*int*/void combine(int a,int b){
int ra=seek(a),rb=seek(b);
if(ra==rb) return /*0*/;
f[ra]=rb;
cnt[rb]+=cnt[ra];//每个集合的点.
//return (cnt[rb]-cnt[ra])*cnt[ra];//两个集合合并,增加在该费用下可连通的点对.
}
int main(){
int n,m,k;
while(~scanf("%d%d%d",&n,&m,&k)){
for(int i=1;i<=n;i++) f[i]=i,cnt[i]=1; //初始化cnt[i]=1;
for(int i=1;i<=m;i++) scanf("%d%d%d",&e[i].from,&e[i].to,&e[i].val);
sort(e+1,e+m+1);
for(int i=1;i<=k;i++) scanf("%d",&q[i].pro),q[i].id=i;
sort(q+1,q+k+1);
int sum=0,en=1; //edge_num
for(int i=1;i<=k;i++){ //离线处理.
while(en<=m&&e[en].val<=q[i].pro){
//sum+=combine(e[en].from,e[en].to);
combine(e[en].from,e[en].to),++en;
}
int ans=0;
for(int i=1;i<=n;i++) if(f[i]==i) ans+=(cnt[i]*(cnt[i]-1))>>1;
//fin[q[i].id]=sum;
fin[q[i].id]=ans;
}
for(int i=1;i<=k;i++) printf("%d\n",fin[i]);
}
}