zoukankan      html  css  js  c++  java
  • #并查集#JZOJ 4223 旅游

    题目

    多次询问有多少个无序点对((x,y))
    满足至少有一条最大边权(leq d)的路径


    分析

    离线询问,用并查集加边,每次产生的贡献为(2*siz[x]*siz[y])


    代码

    #include <cstdio>
    #include <cctype>
    #include <algorithm>
    #define rr register
    using namespace std;
    const int N=100011; typedef long long lll;
    struct rec{int x,rk;}q[N]; struct node{int x,y,w;}e[N];
    int n,m,Q,son[N],f[N]; lll ans[N],now;
    inline signed iut(){
    	rr int ans=0; rr char c=getchar();
    	while (!isdigit(c)) c=getchar();
    	while (isdigit(c)) ans=(ans<<3)+(ans<<1)+(c^48),c=getchar();
    	return ans;
    }
    inline void print(lll ans){
    	if (ans>9) print(ans/10);
    	putchar(ans%10+48);
    }
    bool cmp1(node x,node y){return x.w<y.w;}
    bool cmp2(rec x,rec y){return x.x<y.x;}
    inline signed getf(int u){return f[u]==u?u:f[u]=getf(f[u]);}
    signed main(){
    	for (rr int Test=iut();Test;--Test){
    		n=iut(),m=iut(),Q=iut();
    		for (rr int i=1;i<=m;++i)
    		    e[i]=(node){iut(),iut(),iut()};
    		for (rr int i=1;i<=n;++i) son[i]=1,f[i]=i;
    		sort(e+1,e+1+m,cmp1);
    		for (rr int i=1;i<=Q;++i) q[i]=(rec){iut(),i};
    		sort(q+1,q+1+Q,cmp2);
    		for (rr int i=1,j=1;i<=Q;++i){
    			for (;j<=m&&e[j].w<=q[i].x;++j){
    				rr int fa=getf(e[j].x),fb=getf(e[j].y);
    				if (fa>fb) fa^=fb,fb^=fa,fa^=fb;
    				if (fa!=fb){
    					now+=2ll*son[fa]*son[fb];
    					f[fa]=fb,son[fb]+=son[fa];
    				}
    			}
    			ans[q[i].rk]=now;
    		}
    		for (rr int i=1;i<=Q;++i) print(ans[i]),putchar(10);
    	}
    	return 0;
    } 
    
  • 相关阅读:
    变量属性
    String类
    Random类
    Scanner类
    文本与文本域对齐
    Java list集合排序
    float属性影响后续元素排版问题
    查询满足条件的最新数据(逐步优化,mysql、达梦数据库)
    关于select下拉框选择触发事件
    JQuery获取父,子,兄弟节点
  • 原文地址:https://www.cnblogs.com/Spare-No-Effort/p/13509404.html
Copyright © 2011-2022 走看看