• #并查集#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;
    } 
    
  • 相关阅读:
    使用VisualStudio2015开发QT项目
    界面控件
    SmartGit 试用过期
    视图和模型变换
    模型变换和视图变换
    一元二次方程
    论cudnn与cuda之间的关系,和实际例子测试。
    在Ubuntu 18.04上安装Tensorflow
    ubuntu14.04安装CUDA8.0
    Windows10系统远程桌面连接出现卡顿如何解决
  • 原文地址:https://www.cnblogs.com/Spare-No-Effort/p/13509404.html
Copyright © 2020-2023  润新知