zoukankan      html  css  js  c++  java
  • [HDU

    大意:告诉你有n个点  m个边的无向图  

    然后问有多少点对  他们的路径上节点之间的距离都少于 x

    思路:

    并查集

    离线处理。将边权值按从小到大排序,查询标号后按照从小到大排序。对于每次查询,依次将比当前查询值小的边加入并查集。

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    int t;
    int n,m,q;
    struct  path
    {
        int starts;
        int ends;
        int weight;
         bool operator <(const path &x)const{
          return weight<x.weight;
         }
    }P[100000 + 5];
    struct input
    {
        int id;
        int limit;
        bool operator <(const input &x)const{
          return limit < x.limit;
         }
    }L[100000 + 5];
    long long ans[5000 + 5];
    int father[20000 + 5];
    int cnt[20000 + 5];
    
    int Find(int x)
    {
        return father[x] == x ? x : father[x] = Find(father[x]);
    }
    
    void init()
    {
        for (int j = 1; j <= n; j++)
        {
            father[j] = j;
            cnt[j] = 1;
        }
        memset(ans,0,sizeof(ans));
    }
    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].starts, &P[i].ends, &P[i].weight);
            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 cur = 0;
            long long sum = 0;
            for (int i = 0; i < q; i++)
            {
                while (cur < m && L[i].limit >= P[cur].weight)
                {
                    int fstarts = Find(P[cur].starts);
                    int fends = Find(P[cur].ends);
                    if(fstarts != fends)
                    {
                        sum += cnt[fstarts] * cnt[fends]; //将总联通块合并,再将合并之前的已有的减去,得到的算式化简得
                        father[fends] = fstarts;
                        cnt[fstarts] += cnt[fends];
                    }
                    cur++;
                }
                ans[L[i].id] = sum;
            }
            for(int i = 0; i < q; i++)
                printf("%lld
    ", 2 * ans[i]);
    }
    return 0;
    }
  • 相关阅读:
    Topcoder SRM656div1 250 ( 期望DP )
    SCAU 2015 GDCPC team_training1
    第五次群赛暨清明节专场
    HDU 2783 You’ll be Working on the Railroad(最短路)
    HDU 4013 Distinct Subtrees(树的最小表示)
    HDU 4014 Jimmy’s travel plan(图计数)
    SCAU 2015 GDCPC team_training0
    HDU 1024 Max Sum Plus Plus (递推)
    UVA 12849 Mother’s Jam Puzzle( 高斯消元 )
    HDU 4285 circuits( 插头dp , k回路 )
  • 原文地址:https://www.cnblogs.com/Vikyanite/p/11385836.html
Copyright © 2011-2022 走看看