zoukankan      html  css  js  c++  java
  • 【旅游】题解

    题目

    题目描述

    这里写图片描述

    输入

    这里写图片描述

    输出

    这里写图片描述

    样例输入

    1
    5 5 3
    2 3 6334
    1 5 15724
    3 5 5705
    4 3 12382
    1 3 21726
    6000
    10000
    13000
    

    样例输出

    2
    6
    12
    

    数据制约

    这里写图片描述

    分析

    先把路径和询问也按权值排序,依次按权值把边加入图中,则增加的边数就是边的两头所在的连通块的节点数的积再乘2(如果在同一个连通块就不用),再用并查集维护就可以了。

    #include <cmath>
    #include <cstdio>
    #include <cstdlib>
    #include <iostream>
    int n,m,tot,q,test;
    using namespace std;
    int a[110000][4],bcj[21000],ans[6000],bl[21000],qu[6000][3];
    //bl数组是以x为祖宗的连通块的节点数,bcj即并查集
    void q1(int l,int r)
    {
    	int i=l,j=r,mid=a[(l+r)/2][3],e;
    	while(i<j)
    	{
    		while(a[i][3]<mid) i++;
    		while(a[j][3]>mid) j--;
    		if(i<=j)
    		{
    			e=a[i][2];
    			a[i][2]=a[j][2];
    			a[j][2]=e;
    			e=a[i][1];
    			a[i][1]=a[j][1];
    			a[j][1]=e;
    			e=a[i][3];
    			a[i][3]=a[j][3];
    			a[j][3]=e;
    			i++;
    			j--;
    		}
    	}
    	if(i<r) q1(i,r);
    	if(l<j) q1(l,j);
    }
    void q2(int l,int r)
    {
    	int i=l,j=r,mid=qu[(l+r)/2][1],e;
    	while(i<j)
    	{
    		while(qu[i][1]<mid) i++;
    		while(qu[j][1]>mid) j--;
    		if(i<=j)
    		{
    			e=qu[i][1];
    			qu[i][1]=qu[j][1];
    			qu[j][1]=e;
    			e=qu[i][2];
    			qu[i][2]=qu[j][2];
    			qu[j][2]=e;
    			i++;
    			j--;
    		}
    	}
    	if(i<r) q2(i,r);
    	if(l<j) q2(l,j);
    }
    int zz(int x)
    {
    	if(x==bcj[x]) return x;
    	bcj[x]=zz(bcj[x]);
    	return bcj[x];
    }
    int main()
    {
    	cin>>test;
    	int i,j,k,x,y,l;
    	while(test--)
    	{
    		scanf("%d%d%d",&n,&m,&q);
    		fill(qu[1],qu[1]+5600,0);
    		fill(qu[2],qu[2]+5600,0);
    		for(i=1;i<=n;i++)
    		{
    		    bcj[i]=i;
    		    bl[i]=1;
    		}
    		for(i=1;i<=m;i++)
    		{
    			scanf("%d%d%d",&a[i][1],&a[i][2],&a[i][3]);
    		}
    		for(i=m+1;i<=100000;i++)
    		    a[m+1][1]=a[m+1][2]=a[m+1][3]=200000000;
    		q1(1,m);
    		for(i=1;i<=q;i++)
    		{
    			scanf("%d",&qu[i][1]);
    			qu[i][2]=i;
    		}
    		q2(1,q);
    		j=1;
    		int t=0;//t用来累加
    		for(i=1;i<=q;i++)
    		{
    			while(qu[i][1]>=a[j][3] && j<m)
    			{
    				x=zz(a[j][1]);//找祖宗
    				y=zz(a[j][2]);//找祖宗
    				if(x!=y)
    				{
    					bcj[y]=x;
    					t+=bl[x]*bl[y]*2;
    					bl[x]+=bl[y];
    					bl[y]=0;
    				}
    				j++;
    			}
    			ans[qu[i][2]]=t;
    		}
    		for(i=1;i<=q;i++)
    		{
    		    printf("%d
    ",ans[i]);
    		}
    	}
    }
    
  • 相关阅读:
    ffmpeg rtmp推流 视频转码
    java日志发展史 log4j slf4j log4j2 jul jcl 日志和各种桥接包的关系
    nginx stream 流转发,可以转发rtmp、mysql访问流,转发rtmp、jdbc请求
    java web http 转https 通过nginx代理访问
    linux 服务器磁盘挂载
    novnc 通过websockify代理 配置多点访问
    linux 文件服务 minio 安装部署配置
    AOP实现原理,手写aop
    java 泛型
    JAVA反射getGenericSuperclass()用法
  • 原文地址:https://www.cnblogs.com/chen1352/p/8992973.html
Copyright © 2011-2022 走看看