zoukankan      html  css  js  c++  java
  • Travel(HDU 5441 2015长春区域赛 带权并查集)

    Travel

    Time Limit: 1500/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
    Total Submission(s): 2404    Accepted Submission(s): 842


    Problem Description
    Jack likes to travel around the world, but he doesn’t like to wait. Now, he is traveling in the Undirected Kingdom. There are n cities and m bidirectional roads connecting the cities. Jack hates waiting too long on the bus, but he can rest at every city. Jack can only stand staying on the bus for a limited time and will go berserk after that. Assuming you know the time it takes to go from one city to another and that the time Jack can stand staying on a bus is x minutes, how many pairs of city (a,b) are there that Jack can travel from city a to b without going berserk?
     
    Input
    The first line contains one integer T,T5, which represents the number of test case.

    For each test case, the first line consists of three integers n,m and q where n20000,m100000,q5000. The Undirected Kingdom has n cities and mbidirectional roads, and there are q queries.

    Each of the following m lines consists of three integers a,b and d where a,b{1,...,n} and d100000. It takes Jack d minutes to travel from city a to city b and vice versa.

    Then q lines follow. Each of them is a query consisting of an integer x where x is the time limit before Jack goes berserk.

     
    Output
    You should print q lines for each test case. Each of them contains one integer as the number of pair of cities (a,b) which Jack may travel from a to b within the time limit x.

    Note that (a,b) and (b,a) are counted as different pairs and a and b must be different cities.
     
    Sample Input

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

    Sample Output
    2
    6
    12
    新方法,带权的并查集,在并查集集合里面根节点记录了该树的节点个数num,我们每次都把下标较小的点作为根节点。
    题目大意:
      给定n个城市,以及m条城市之间的道路。每条道路都有一个权值val,给定一个q,求用到所有边权不大于这个值的的情况下,能够互相到达的点对的个数。
    思路:
      对边权值,询问值q排序从小到大,然后将小于q的边的两端点合并,下标小的点设为根节点,记录树的规模。
      每次合并,ans+=2*num[u]*num[v];
     1 #include <iostream>
     2 #include <cstring>
     3 #include <algorithm>
     4 #include <cstdio>
     5 #define Max 20000+5
     6 using namespace std;
     7 struct edge
     8 {
     9     int s,e,val;
    10 }a[100000+5];
    11 struct ques
    12 {
    13     int d,id,res;
    14 }p[5005];
    15 int per[Max],num[Max];
    16 int n,m,q;
    17 bool cmp(ques a,ques b)
    18 {
    19     return a.d<=b.d;
    20 }
    21 bool cmp1(ques a,ques b)
    22 {
    23     return a.id<b.id;
    24 }
    25 void init()
    26 {
    27     for(int i=0;i<=n;i++)
    28     {
    29         per[i]=i;
    30         num[i]=1;
    31     }
    32     for(int i=0;i<=q;i++)
    33         p[i].res=0;
    34 }
    35 int find(int x)
    36 {
    37     if(x==per[x])
    38         return x;
    39     return per[x]=find(per[x]);
    40 }
    41 int unite(int a,int b)
    42 {
    43     a=find(a);
    44     b=find(b);
    45     if(a<b)            //a最大
    46         swap(a,b);
    47     per[a]=b;        //根节点下标最小,记录树的节点个数
    48     num[b]+=num[a];
    49     return 0;
    50 }
    51 bool cmp2(edge a,edge b)
    52 {
    53     return a.val<b.val;
    54 }
    55 int main()
    56 {
    57     int T;
    58     int i,j;
    59     freopen("in.txt","r",stdin);
    60     scanf("%d",&T);
    61     while(T--)
    62     {
    63         scanf("%d%d%d",&n,&m,&q);
    64         init();
    65         for(i=0;i<m;i++)
    66             scanf("%d%d%d",&a[i].s,&a[i].e,&a[i].val);
    67         for(i=0;i<q;i++)
    68         {
    69             scanf("%d",&p[i].d);
    70             p[i].id=i;
    71         }
    72         sort(a,a+m,cmp2);
    73         sort(p,p+q,cmp);
    74         j=0;
    75         int t1,t2,ans=0;
    76         for(i=0;i<q;i++)
    77         {
    78             while(j<m&&a[j].val<=p[i].d)
    79             {
    80                 t1=find(a[j].s);
    81                 t2=find(a[j].e);
    82                 j++;
    83                 if(t1!=t2)
    84                 {
    85                     ans+=2*num[t1]*num[t2];
    86                     unite(t1,t2);
    87                 }
    88             }
    89             p[i].res=ans;
    90         }
    91         sort(p,p+q,cmp1);
    92         for(i=0;i<q;i++)
    93             printf("%d
    ",p[i].res);
    94     }
    95 }
  • 相关阅读:
    Counting Stars hdu
    Color it hdu
    steins;Gate
    原根
    3-idiots
    Tree
    洛谷P1352 没有上司的舞会
    洛谷P1131 时态同步
    洛谷P3177 树上染色
    Codeforces Round #617 (Div. 3)
  • 原文地址:https://www.cnblogs.com/a1225234/p/5182048.html
Copyright © 2011-2022 走看看