zoukankan      html  css  js  c++  java
  • hdu3938 Portal

    Problem Description
    ZLGG found a magic theory that the bigger banana the bigger banana peel .This important theory can help him make a portal in our universal. Unfortunately, making a pair of portals will cost min{T} energies. T in a path between point V and point U is the length of the longest edge in the path. There may be lots of paths between two points. Now ZLGG owned L energies and he want to know how many kind of path he could make.
     

    Input
    There are multiple test cases. The first line of input contains three integer N, M and Q (1 < N ≤ 10,000, 0 < M ≤ 50,000, 0 < Q ≤ 10,000). N is the number of points, M is the number of edges and Q is the number of queries. Each of the next M lines contains three integers a, b, and c (1 ≤ a, b ≤ N, 0 ≤ c ≤ 10^8) describing an edge connecting the point a and b with cost c. Each of the following Q lines contain a single integer L (0 ≤ L ≤ 10^8).
     

    Output
    Output the answer to each query on a separate line.
     

    Sample Input
    10 10 10 7 2 1 6 8 3 4 5 8 5 8 2 2 8 9 6 4 5 2 1 5 8 10 5 7 3 7 7 8 8 10 6 1 5 9 1 8 2 7 6
     

    Sample Output
    36 13 1 13 36 1 36 2 16
    13

    题目要求a、b两点之间所有的路径中的最大边的最小值。

    这题可以用并查集做,因为询问次数很多,所以要离线操作。设数组num[i],只记录i所在集合的总顶点数(一开始以为是记录边的,其实是记录顶点的),先对所有的边排序,从小到大,(其实可以看做是依次枚举最大边的最小值,因为如果这条线段的两端点不在一个集合,即两个集合的边不相连,那么这条线段就起到了桥梁的作用,也就是说任意两个集合的点相连都要通过这条边,因为之前两个集合的最大边的最小值都符合条件,那么如果这条线段也符合条件,就可以把两个集合的点都连起来),因为能量大的值一定包括能量小的路径,所以每次初始化的时候p[i].sum=p[i-1].sum;

    #include<iostream>
    #include<stdio.h>
    #include<string.h>
    #include<math.h>
    #include<algorithm>
    #include<map>
    #include<string>
    using namespace std;
    int pre[10006],num[10006];
    struct edge
    {
    	int from,to,len;
    }e[50006];
    struct node
    {
    	int id,num,sum;
    }q[10006];
    
    bool cmp1(edge a,edge b)
    {
    	int temp;
    	if(a.len>b.len){
    		temp=a.from;a.from=b.from;b.from=temp;
    		temp=a.to;a.to=b.to;b.to=temp;
    		return a.len<b.len;
    	}
    	return a.len<b.len;
    }
    bool cmp2(node a,node b)
    {
    	int temp;
    	if(a.num>b.num){
    		temp=a.id;a.id=b.id;b.id=temp;
    		return a.num<b.num;
    	}
    	return a.num<b.num;
    }
    bool cmp3(node a,node b)
    {
    	int temp;
    	if(a.id>b.id){
    		temp=a.sum;a.sum=b.sum;b.sum=temp;
    		return a.id<b.id;
    	}
    	return a.id<b.id;
    }
    int find(int x)
    {
    	int r=x,i,j=x;
    	while(r!=pre[r])r=pre[r];
    	while(j!=pre[j]){
    		i=pre[j];
    		pre[j]=r;
    		j=i;
    	}
    	return r;
    }
    
    int main()
    {
    	int n,m,i,j,a,b,c,p,t1,t2,ans;
    	while(scanf("%d%d%d",&n,&m,&p)!=EOF)
    	{
    		for(i=0;i<=n;i++){
    			pre[i]=i;num[i]=1;
    		}
    		for(i=1;i<=m;i++){
    			scanf("%d%d%d",&e[i].from,&e[i].to,&e[i].len);
    		}
    		sort(e+1,e+1+m,cmp1);
    		for(i=1;i<=p;i++){
    			scanf("%d",&q[i].num);
    			q[i].id=i;
    		}
    		sort(q+1,q+p+1,cmp2);
    		ans=1;
    		q[0].sum=0;
    		for(i=1;i<=p;i++){
    			q[i].sum=q[i-1].sum;
    			while(ans<=m && e[ans].len<=q[i].num){
    			     t1=find(e[ans].from);t2=find(e[ans].to);
    			     if(t1==t2){
         				ans++;continue;
         			 }
    			     pre[t1]=t2;
    			     q[i].sum+=num[t1]*num[t2];
    			     num[t2]+=num[t1];
    			     ans++;
    			}
    		}
    		
    		sort(q+1,q+1+p,cmp3);
    		for(i=1;i<=p;i++){
    			printf("%d
    ",q[i].sum);
    		}
    	}
    	return 0;
    }


  • 相关阅读:
    转载:【Oracle 集群】RAC知识图文详细教程(三)--RAC工作原理和相关组件
    转载:【Oracle 集群】RAC知识图文详细教程(一)--集群概念介绍
    转载:【Oracle 集群】RAC知识图文详细教程(二)--Oracle 集群概念及原理
    题目总结
    面试题(包含答案)
    ElementUI动态表格数据转换formatter
    父组件搜索列表 给 子组件传值问题
    项目提取公共接口方法
    数组常用方法总结
    vue全局注册
  • 原文地址:https://www.cnblogs.com/herumw/p/9464801.html
Copyright © 2011-2022 走看看