///1085422276 #include<bits/stdc++.h> using namespace std ; typedef long long ll; #define mem(a) memset(a,0,sizeof(a)) #define meminf(a) memset(a,127,sizeof(a)); #define TS printf("111111\n"); #define FOR(i,a,b) for( int i=a;i<=b;i++) #define FORJ(i,a,b) for(int i=a;i>=b;i--) #define READ(a,b,c) scanf("%d%d%d",&a,&b,&c) #define inf 100000 inline ll read() { ll x=0,f=1; char ch=getchar(); while(ch<‘0‘||ch>‘9‘) { if(ch==‘-‘)f=-1; ch=getchar(); } while(ch>=‘0‘&&ch<=‘9‘) { x=x*10+ch-‘0‘; ch=getchar(); } return x*f; } //**************************************** #define maxn 1000000+50 struct ss { int u,v,w; bool operator <(const ss &x)const{ return w<x.w; } }a[maxn]; ll ans[maxn]; int num[maxn],parent[maxn],n,m,q; struct sss { int v,id; bool operator <(const sss &x)const{ return v<x.v; } }Ans[maxn]; int finds(int x){ if(x!=parent[x])parent[x]=finds(parent[x]); return parent[x]; } void init() { FOR(i,0,n){parent[i]=i;num[i]=1;} mem(ans); } int main() { int T=read(); while(T--) { scanf("%d%d%d",&n,&m,&q); FOR(i,1,m) { scanf("%d%d%d",&a[i].u,&a[i].v,&a[i].w); } sort(a+1,a+m+1); // FOR(i,1,m){cout<<a[i].u<<" "<<a[i].v<<" "<<a[i].w<<endl;} FOR(i,1,q) { scanf("%d",&Ans[i].v); Ans[i].id=i; } sort(Ans+1,Ans+q+1); init(); //FOR(i,1,q)cout<<Ans[i].v<<" "<<Ans[i].id<<endl; ll aa=0; int j=1; FOR(i,1,q) { while(j<=m&&Ans[i].v>=a[j].w) { int fx=finds(a[j].u); int fy=finds(a[j].v); if(fx!=fy) { parent[fy]=fx; aa+=num[fx]*num[fy]; num[fx]+=num[fy]; } j++; } ans[Ans[i].id]=aa*2; } for(int i=1;i<=q;i++) printf("%I64d\n", ans[i]); } return 0; }
给你一个图,n个点,m条边,并有边权值,q个询问,每个询问是一个限制值,问你多少对不同的(S,T)路径上的最小权值不超过这个限制值,(S,T)与(T,S)是不同的。
原文:http://www.cnblogs.com/zxhl/p/4869727.html