码迷,mamicode.com
首页 > 其他好文 > 详细

hdu 5441 并查集

时间:2015-10-31 00:26:20      阅读:303      评论:0      收藏:0      [点我收藏+]

标签:

Travel

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

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 m技术分享
bidirectional 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
 
Source
 
 
 
其实这道题 队里之前讲过的 一直没有写...gg
一直TLE 然后学习了离线并查集 先排序 一边扫 一边存  还有计算几对的姿势也不好  he+=mp[ss]*mp[ee]
然后 然后 按着这个敲了还是超时 gg  太菜比了  并查集 以为了解的很深了
如下正解
int Find(int mubiao)
{
    if(parent[mubiao]!=mubiao)
        parent[mubiao]=Find(parent[mubiao]);//原来的姿势一直有bug
    return parent[mubiao];
}
 
 
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int t;
int n,m,q;
struct  path
{
    int s;
    int e;
    int dis;
     bool operator <(const path &x)const{
      return dis<x.dis;
     }
}P[100005];
struct limi
{
    int id;
    int limit;
    bool operator <(const limi &x)const{
      return limit<x.limit;
     }
}L[100005];
__int64 re[5005];
int parent[20005];
int mp[20005];
int Find(int mubiao)
{
    if(parent[mubiao]!=mubiao)
        parent[mubiao]=Find(parent[mubiao]);
    return parent[mubiao];
}
void init()
{
    for(int j=1;j<=n;j++)
    {
        parent[j]=j;
        mp[j]=1;
    }
    memset(re,0,sizeof(re));
}
int main()
{
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d%d",&n,&m,&q);
        for(int i=0;i<m;i++)
            scanf("%d%d%d",&P[i].s,&P[i].e,&P[i].dis);
        sort(P,P+m);
        for(int i=0;i<q;i++)
        {
            L[i].id=i;
            scanf("%d",&L[i].limit);
        }
        sort(L,L+q);
        init();
        int gg=0;
        __int64 he=0;
        for(int i=0;i<q;i++)
        {
            while(gg<m&&L[i].limit>=P[gg].dis)
            {
                int ss=Find(P[gg].s);
                int ee=Find(P[gg].e);
                if(ss!=ee)
                {
                    he+=mp[ss]*mp[ee];
                    parent[ee]=ss;
                    mp[ss]+=mp[ee];
                }
                gg++;
            }
            re[L[i].id]=he;
        }
        for(int i=0;i<q;i++)
            printf("%I64d\n",2*re[i]);
}
return 0;
}

 

hdu 5441 并查集

标签:

原文地址:http://www.cnblogs.com/hsd-/p/4924673.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!