首页 > 其他分享 >hdu 5441 长春区域赛网络赛 1005 Travel(并查集)

hdu 5441 长春区域赛网络赛 1005 Travel(并查集)

时间:2023-04-23 21:37:13浏览次数:51  
标签:hdu const int MAX 5441 查集 num include 边权


题目链接:

hdu 5441


题目大意:

有一个n个点的无向图,给出m条边的边权,给出q次询问,每次给出一个值,求用到所有边权不大于这个值的边的情况下,能够互相到达的点对的个数(自己到自己不算)


题目分析:

  • 首先我们对于边按照边权从小到大排序,对于询问按照值从小到大排序。
  • 枚举每次询问,从前到后扫描边,如果下一条边的边权大于当前的询问的值,那么停止,利用并查集记录每个联通块的点的个数。
  • 每次如果某两个联通块合并,那么最终结果就是增加了(num[1]+num[2])×(num[1]+num[2]-1) - num[1] × (num[1]-1) - num[2] ×(num[2]-1)
  • 复杂度O(m)

AC代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define MAX 20007

using namespace std;

int fa[MAX],num[MAX],t,n,m,q,pp[MAX];

struct Query
{
    int x,id;
    bool operator < ( const Query& a )const 
    {
        return x < a.x;
    }
}a[MAX];


struct Edge
{
    int u,v,w;
    bool operator < ( const Edge& a ) const 
    {
        return w < a.w;
    }
}e[MAX*5];

void init ( )
{
    for ( int i = 1 ; i <= n ; i++ )
    {
        num[i] = 1;
        fa[i] = i;
    }
}

int _find ( int x )
{
    return fa[x] == x? x : fa[x] = _find ( fa[x] );
}

void _union ( int x , int y )
{
    x = _find ( x );
    y = _find ( y );
    if ( y < x ) swap ( x , y );
    fa[y] = x;
    num[x] += num[y];
}

int main ( )
{
    scanf ( "%d" ,&t );
    while ( t-- )
    {
        int ans = 0;
        scanf ( "%d%d%d" , &n , &m , &q );
        init ( ); 
        for ( int i = 0 ; i < m ; i++ )
            scanf ( "%d%d%d" , &e[i].u , &e[i].v , &e[i].w );
        sort ( e , e+m );
        int j = 0;
        for ( int i = 0 ; i < q ; i++ )
        {
            a[i].id = i;
            scanf ( "%d" , &a[i].x );
        }
        sort ( a , a+q );
        for ( int i = 0 ; i < q ; i++ )
        {
            while ( j < m && e[j].w <= a[i].x )
            {
                int u = _find ( e[j].u );
                int v = _find ( e[j].v );
                j++;
                if ( u == v ) continue;
                ans += (num[u]+num[v])*(num[u]+num[v]-1)-num[u]*(num[u]-1) - num[v]*(num[v]-1);
                _union ( u , v );
            }
            pp[a[i].id] = ans;
        }
        for ( int i = 0 ; i < q ; i++ )
            printf ( "%d\n" , pp[i] );
    }
}


标签:hdu,const,int,MAX,5441,查集,num,include,边权
From: https://blog.51cto.com/u_7936627/6218744

相关文章

  • hdu 5442 长春区域赛网络赛 1006 Favorite Donut(后缀数组)
    题目链接:hdu5442题目大意:给出一个环,每颗珠子有一个甜度,选择第一个珠子和吃的方向,问得到的吃珠子的字符串的字典序最大的,如果有多个,选取位置最靠前的,如果还是多个,选择顺时针吃的。题目分析:-首先构造一个字符串,首先正着按环吃,那么就是字符串正着写两遍,连接在一起;中间用没有出现过的......
  • hdu 5446 长春区域赛网络赛1010 Unknown Treasure(lucas定理+中国剩余定理+移位乘法)
    题目链接:hdu5446题目大意:求出Cmn%M,M=p1⋅p2⋯pk题目分析:首先对于每个质数pi我们,我们可以利用Lucas定理求出Cmn%pi的值,Lucas定理如下:Cmn%p=Cm/pn/p⋅Cm%pn%p%p然后我们可以利用中国剩余定理求取最后答案:M=∏i=1kpi,Mi=M/piCmn%M=∑i=1kCmn%pi⋅Mi⋅inv[Mi]因为做乘法......
  • hdu 5444 长春区域赛网络赛 1008 Elven Postman(模拟)
    题目链接:hdu5444题目大意:给出一个序列,这个序列的第一个点是树的根节点,每次操作从当前点走到当前最靠右的每走过的点(点的序号越小越靠右),问将物品从根送到某个点的行进路线.题目分析:个人认为难在题意。。。构造出这个树之后,直接从目的地走回根节点就可以得到要求的路径。然后如何构......
  • HDU 5389 Zero Escape(DP + 滚动数组)
    ZeroEscapeTimeLimit:2000/1000MS(Java/Others)    MemoryLimit:131072/131072K(Java/Others)TotalSubmission(s):864    AcceptedSubmission(s):438ProblemDescriptionZeroEscape,isavisualnoveladventurevideogamedirectedbyKotar......
  • 并查集及其扩展(附例题与完整讲解cpp)
    文章目录基础并查集1.P1551亲戚2.P1536村村通种类并查集1.P1892[BOI2003]团伙2.P1525[NOIP2010提高组]关押罪犯3.P2024[NOI2001]食物链带权并查集基础并查集并查集就是用来维护一些元素之间的关系的集合。例如A的亲戚是B,则我们可以把A与B放到同一个集合中,表示AB属......
  • HDU1873 看病要排队
    E- 看病要排队TimeLimit:1000MS     MemoryLimit:32768KB     64bitIOFormat:%I64d&%I64uDescription看病要排队这个是地球人都知道的常识。不过经过细心的0068的观察,他发现了医院里排队还是有讲究的。0068所去的医院有三个医生(汗,这么......
  • HDU 1114 Piggy-Bank
    F- Piggy-BankTimeLimit:1000MS     MemoryLimit:32768KB     64bitIOFormat:%I64d&%I64uSubmit StatusDescriptionBeforeACMcandoanything,abudgetmustbepreparedandthenecessaryfinancialsupportobtained.Themaininc......
  • HDU 1869 六度分离
    六度分离TimeLimit:1000MS     MemoryLimit:32768KB     64bitIOFormat:%I64d&%I64uSubmit Status Practice HDU1869Description1967年,美国著名的社会学家斯坦利・米尔格兰姆提出了一个名为“小世界现象(smallworldphenom......
  • HDU 1527 取石子游戏(博弈论)
    取石子游戏TimeLimit:2000/1000MS(Java/Others)    MemoryLimit:65536/32768K(Java/Others)TotalSubmission(s):3717    AcceptedSubmission(s):1868ProblemDescription有两堆石子,数量任意,可以不同。游戏开始由两个人轮流取石子。游戏规定,每次有......
  • 23-4-15--并查集--部落
    在一个社区里,每个人都有自己的小圈子,还可能同时属于很多不同的朋友圈。我们认为朋友的朋友都算在一个部落里,于是要请你统计一下,在一个给定社区中,到底有多少个互不相交的部落?并且检查任意两个人是否属于同一个部落。输入格式:输入在第一行给出一个正整数N(≤104),是已知小圈子的个数......