HDOJ5441(图论中的并查集)
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int MAX_N=100005; const int MAX_V=20005; const int MAX_Q=5005; struct edge{ int from,to,cost; }es[MAX_N]; int V,E,Q; bool comp(const edge &e1,const edge &e2) { return e1.cost < e2.cost; } void getMap() { for(int i=0;i<E;i++) { scanf("%d %d %d",&es[i].from,&es[i].to,&es[i].cost); } sort(es,es+E,comp); } int par[MAX_V]; int nodes[MAX_V]; void Init() { for(int i=0;i<=V;i++) { par[i]=i; nodes[i]=1; } } int Find(int x) { if(par[x]==x) return x; return par[x]=Find(par[x]); } struct Query{ int limit; int index; }query[MAX_Q]; bool comp1(Query q1,Query q2) { return q1.limit < q2.limit; } long long ans[MAX_Q]; void Solve() { for(int i=0;i<Q;i++) { scanf("%d",&query[i].limit); query[i].index=i; } sort(query,query+Q,comp1); long long sum=0; int j=0; for(int i=0;i<Q;i++) { while(j<E&&query[i].limit>=es[j].cost) { int u=Find(es[j].from); int v=Find(es[j].to); if(u!=v) { sum+=2*nodes[u]*nodes[v]; par[u]=v;// 将u,v两集合合并,v为祖先 nodes[v]+=nodes[u]; } j++; } ans[query[i].index]=sum; } // 优化时间,将query全部输入之后再集体输出 for(int i=0;i<Q;i++) { printf("%I64d\n",ans[i]); } } int main() { int t; scanf("%d",&t); while(t--) { scanf("%d %d %d",&V,&E,&Q); getMap(); Init(); Solve(); } return 0; }