Travel---hdu5441(并查集)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5441

题意:是有n个城市,m条边包含u v w;代表u到v的时间是w;

给q的时间x,求在x时间内Jack可以到达多少对城市;其中ab和ba是不同的;

1
5 5 3
2 3 6334
1 5 15724
3 5 5705
4 3 12382
1 3 21726
6000///////可以到达35和53;
10000//////2 5 3是可以相互到达的所以有6种;
13000///////2 3 5 4是想通的有12种;

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
using namespace std;
#define N 100100

int f[20100], r[20100], Ans[5005];

struct node
{
    int u, v, w, index;
}a[N], b[5005];

int cmp(node p, node q)
{
    return p.w < q.w;
}

int Find(int x)
{
    if(x!=f[x])
        f[x] = Find(f[x]);
    return f[x];
}

int main()
{
    int T, n, m, q;

    scanf("%d", &T);
    while(T--)
    {
        scanf("%d%d%d", &n, &m, &q);

        for(int i=0; i<=n;i++)
        {
            f[i] = i;
            r[i] = 1;
        }

        for(int i=0; i<m; i++)
            scanf("%d%d%d", &a[i].u, &a[i].v, &a[i].w);

        for(int i=0; i<q; i++)
        {
            scanf("%d", &b[i].w);
            b[i].index = i;
        }

        sort(a, a+m, cmp);
        sort(b, b+q, cmp);

        int j=0;
        int ans = 0;
        for(int i=0; i<q; i++)
        {
            while(j<m && b[i].w>=a[j].w)///满足条件的
            {
                int pa = Find(a[j].u);
                int pb = Find(a[j].v);
                if(pa != pb)
                {
                    f[pa] = pb;
                    ans += r[pa]*r[pb];///加上两个集合的数任意组合;
                    r[pb]+=r[pa];///r[i]代表i的根节点所包含的元素个数;
                }
                j++;
            }
            Ans[b[i].index] = ans*2;///保存结果,ab和ba是不一样的;
        }
        for(int i=0; i<q; i++)
            printf("%d\n", Ans[i]);
    }
    return 0;
}

时间: 2024-08-01 21:02:07

Travel---hdu5441(并查集)的相关文章

HDU-5441 Travel 离线-并查集

Travel Time Limit: 1500/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 4680    Accepted Submission(s): 1532 Problem Description Jack likes to travel around the world, but he doesn't like to wait. Now, he is t

【BZOJ-1576】安全路径Travel Dijkstra + 并查集

1576: [Usaco2009 Jan]安全路经Travel Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 1044  Solved: 363[Submit][Status][Discuss] Description Input * 第一行: 两个空格分开的数, N和M * 第2..M+1行: 三个空格分开的数a_i, b_i,和t_i Output * 第1..N-1行: 第i行包含一个数:从牛棚_1到牛棚_i+1并且避免从牛棚1到牛棚i+1最

HDU 5441——Travel——————【并查集+二分查界限】

Travel Time Limit: 1500/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 1313    Accepted Submission(s): 472 Problem Description Jack likes to travel around the world, but he doesn’t like to wait. Now, he is tr

HDU 5441 Travel (并查集+数学+计数)

题意:给你一个带权的无向图,然后q(q≤5000)次询问,问有多少对城市(城市对(u,v)与(v,u)算不同的城市对,而且u≠v)之间的边的长度不超过d(如果城市u到城市v途经城市w, 那么需要城市u到城市w的长度e1≤d,同时城市w到城市v的长度e2≤d). 析:一开始的时候,题意都读错了,怎么看都不对,原来是只要最大的d小于等于x就可以,过了好几天才知道是这样..... 这个题是并查集的应用,先从d小的开始遍历,然后去判断有几个连通块,在连通块中计数,用一个数组即可,运用排列组合的知识可以知

Hdu 5441 Travel(并查集)

题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=5441 思路:离线处理.将边权值按从小到大排序,查询标号后按照从小到大排序.对于每次查询,依次将比当前查询值小的边加入并查集.对于两个符合条件即将合并的连通块增加答案个数num[x]*num[y]*2 .合并:fa[x]=y; num[y]+=num[x]; .最后依次输出结果即可. #include<cstdio> #include<cstring> #include<iostr

hdu 5441 Travel 离线操作+并查集

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5441 题意:给出一张图,有n个点,m条带权边,每次询问给出一个值val,要求删除权值>val的所有边.然后每次询问求多少个点对相连,ab和ba算成两个点对. 思路: 把每条边的权值按照从小到大排序,把每个询问记录下来,按照从小到大排序. 初始图没有边.然后按照询问加入边.对于每个询问,除了已经加入的边,再加入权值比它小的边. 然后用并查集求得每次加一条边后新产生的点对. 用一个数组cnt[i],来记

【bzoj1576/Usaco2009 Jan】安全路经Travel——dijkstra+并查集

Description Input * 第一行: 两个空格分开的数, N和M * 第2..M+1行: 三个空格分开的数a_i, b_i,和t_i Output * 第1..N-1行: 第i行包含一个数:从牛棚_1到牛棚_i+1并且避免从牛棚1到牛棚i+1最短路经上最后一条牛路的最少的时间.如果这样的路经不存在,输出-1. Sample Input 4 5 1 2 2 1 3 2 3 4 4 3 2 1 2 4 3 输入解释: 跟题中例子相同 Sample Output 3 3 6 输出解释: 跟

HDU 5441 Travel(并查集+统计节点个数)

http://acm.hdu.edu.cn/showproblem.php?pid=5441 题意:给出一个图,每条边有一个距离,现在有多个询问,每个询问有一个距离值d,对于每一个询问,计算出有多少点对(x,y)使得在x到y的路径上没有一条边的距离大于d. 思路:只要边距离小于d,那就是可行的,直接加入并查集来维护.并查集需要维护一下树的节点个数. 将边和询问都排序离线处理. 1 #include<iostream> 2 #include<cstdio> 3 #include<

HDU5441 Travel (离线操作+并查集)

Travel Time Limit: 1500/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 2055    Accepted Submission(s): 709 Problem Description Jack likes to travel around the world, but he doesn’t like to wait. Now, he is tr

hdu5441 并查集+克鲁斯卡尔算法

这题计算 一张图上 能走的 点对有多少个  对于每个限制边权 , 对每条边排序,对每个查询排序 然后边做克鲁斯卡尔算法 的时候变计算就好了 #include <iostream> #include <algorithm> #include <string.h> #include <cstdio> #include <vector> #include <queue> using namespace std; const int maxn