这题计算 一张图上 能走的 点对有多少个 对于每个限制边权 , 对每条边排序,对每个查询排序
然后边做克鲁斯卡尔算法 的时候变计算就好了
#include <iostream> #include <algorithm> #include <string.h> #include <cstdio> #include <vector> #include <queue> using namespace std; const int maxn=20005; typedef long long LL; struct edg{ int a,b,d; edg(int ca=0,int cb=0,int cd=0) { a=ca; b=cb; d=cd; } bool operator <(const edg &rhs)const{ return d<rhs.d; } }E[100005]; struct query{ LL id,d; query(LL cid=0, LL cd=0 ){ id=cid; d=cd; } bool operator <(const query &rhs)const { return d<rhs.d; } }Q[5005]; LL S[maxn]; LL num[maxn]; int fa[maxn]; int fin(int a) { return fa[a]=(fa[a]==a)?a:fin(fa[a]); } LL ans[5005]; int main() { int cas; scanf("%d",&cas); for(int cc=1; cc<=cas; cc++) { int n,m,q; scanf("%d%d%d",&n,&m,&q); for(int i=0; i<m; i++)scanf("%d%d%d",&E[i].a,&E[i].b,&E[i].d); for(int i=0; i<=n; i++){fa[i]=i;S[i]=0;num[i]=1;} for(int i=0; i<q; i++) {scanf("%I64d",&Q[i].d);Q[i].id=i; ans[i]=0;} sort(E,E+m); sort(Q,Q+q); int loc=0; LL D=0; for(int i=0; i<q; i++) { while(loc<m&&E[loc].d<=Q[i].d){ int a=E[loc].a,b=E[loc].b; a=fin(a); b=fin(b); if(a==b){ loc++; continue; } D=D-S[a]-S[b]; fa[b]=a; num[a]+=num[b]; S[a]=1LL*num[a]*(num[a]-1); D=D+S[a]; loc++; } ans[Q[i].id]=D; } for(int i=0; i<q; i++) printf("%I64d\n",ans[i]); } return 0; }
时间: 2024-12-27 23:55:17