zoukankan      html  css  js  c++  java
  • hdu 5441 (并查集)

    题意:给你n个点,m条边构成无向图。q个询问,每次一个值,求有多少条路,路中的边权都小于这个值

    a->b 和 b->a算两种

    思路:把权值从小到大排序,询问从小到大排序,如果相连则用并查集相连形成联通块

    x个点可以形成:x * (x - 1)

    如果新增的路使两个联通块和并则数量 增长了:

    (num[1]+num[2])×(num[1]+num[2]-1) - num[1] × (num[1]-1) - num[2] ×(num[2]-1)


    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<cmath>
    #include<algorithm>
    #include<string>
    #include<map>
    #include<set>
    #include<vector>
    #include<queue>
    #include<stack>
    using namespace std;
    typedef long long ll;
    int T,n,m,k;
    int num[20005],par[20005],p[20005];
    
    struct node
    {
        int u,v,w;
        bool operator<(const node&a)const
        {
            return w < a.w;
        }
    } pnode[100005];
    
    struct term
    {
        int id,we;
        bool operator<(const term&a)const
        {
            return we<a.we;
        }
    } te[20005];
    
    int fin(int x)
    {
       return x == par[x]?  x : par[x] = fin(par[x]);
    }
    
    void merg(int x,int y)
    {
        int x1 = fin(x);
        int x2 = fin(y);
        if(x1 < x2)
        {
            par[x2]= x1;
            num[x1] += num[x2];
        }
        else
        {
            par[x1] = x2;
            num[x2] += num[x1];
        }
    }
    
    int main()
    {
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d%d%d",&n,&m,&k);
    
            for(int i = 0; i <= n; i++)
            {
                par[i] = i;
                num[i] = 1;
            }
    
            for(int i = 0; i < m; i++)
                scanf("%d%d%d",&pnode[i].u,&pnode[i].v,&pnode[i].w);
            sort(pnode,pnode+m);
    
            for(int i = 0; i < k; i++)
            {
                te[i].id = i;
                scanf("%d",&te[i].we);
            }
            sort(te,te+k);
            int tt = 0;
            ll ans = 0;
            for(int i = 0; i < k; i++)
            {
                while(tt < m &&  pnode[tt].w <= te[i].we )
                {
                    int u = fin(pnode[tt].u);
                    int v = fin(pnode[tt].v);
                    tt++;
                    if(u == v)
                        continue;
                    ans += (num[u]+num[v])*(num[u]+num[v]-1)-num[u]*(num[u]-1) - num[v]*(num[v]-1);
                    merg(u,v);
                    
                }
                p[te[i].id] = ans;
            }
    
            for(int i = 0;i <k;i++)
                printf("%d
    ",p[i]);
        }
        return 0;
    }
    

      

  • 相关阅读:
    jwt手动生成access_token
    python学习-52 XML模块
    python学习-51 shelve模块
    python学习-50 pickle模块
    python学习-49 json模块
    python学习-48 模块2
    python学习-47 random模块
    python学习-46 时间模块
    python学习-45 模块
    python学习-44 程序的解耦 (不是特别懂的,回头在复习)
  • 原文地址:https://www.cnblogs.com/Przz/p/5409758.html
Copyright © 2011-2022 走看看