zoukankan      html  css  js  c++  java
  • hdu4750(离线并查集+思路)

    题意:

    n个点,m条边的无向图,每条边a b c,点a到点b的权值是c。
    p(0<p<=100000)个人,以下p行每行有一个值t,找出有多少对点(i, j)满足f大于等于t。
    f值的定义:从i点到j点,有好几种走法,每种走法中取路径中权值最大的边值,所有走法中的值中,取最小的那个即为f值

    //#pragma comment(linker, "/STACK:102400000")
    #include<cstdlib>
    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    #include<set>
    #include<map>
    #include<list>
    #include<queue>
    #include<vector>
    #define tree int o,int l,int r
    #define lson o<<1,l,mid
    #define rson o<<1|1,mid+1,r
    #define lo o<<1
    #define ro o<<1|1
    #define ULL unsigned long long
    #define LL long long
    #define inf 0x7fffffff
    #define eps 1e-7
    #define N 10005
    #define M 500009
    using namespace std;
    int m,n,T,t,x,y,u,qn;
    struct Node
    {
        int x,y,val;
        bool operator<(const Node a)const
        {
            return val<a.val;
        }
    } node[M];
    int q[M/5+100],f[M/5+100],ans[M/5+100];
    int s[N],cnt[N];
    bool cmp(int a,int b)
    {
        return q[a]<q[b];
    }
    int find(int x)
    {
        return x==s[x]?x:s[x]=find(s[x]);
    }
    int main()
    {
    #ifndef ONLINE_JUDGE
        freopen("ex.in","r",stdin);
    #endif
    //    scanf("%d",&T);
    //    while(T--)
        int ncase=0;
        while(scanf("%d%d",&n,&m)==2)
        {
            for(int i=0; i<m; ++i)
                scanf("%d%d%d",&node[i].x,&node[i].y,&node[i].val);
            sort(node,node+m);
            scanf("%d",&qn);
            for(int i=0; i<qn; i++)
            {
                scanf("%d",&q[i]);
                f[i]=i;
            }
            sort(f,f+qn,cmp);
            for(int i=0; i<=n; i++)
            {
                s[i]=i;
                cnt[i]=1;
            }
            int tp=0,j=0;
            for(int i=0; i<qn; i++)
            {
                int sub=f[i];
                while(j<m&&node[j].val<q[sub])
                {
    
                    int u=node[j].x,v=node[j].y;
                    int toux=find(u);
                    int touy=find(v);
                    if(toux!=touy)
                    {
                        tp+=cnt[touy]*cnt[toux];
                        s[touy]=toux;
                        cnt[toux]+=cnt[touy];
                    }
                    j++;
                }
                ans[sub]=tp;
            }
            while(j<m)//WA,求tp
            {
                int u=node[j].x,v=node[j].y;
                int toux=find(u);
                int touy=find(v);
                if(toux!=touy)
                {
                    tp+=cnt[touy]*cnt[toux];
                    s[touy]=toux;
                    cnt[toux]+=cnt[touy];
                }
                j++;
            }
            for(int i=0; i<qn; i++)
                printf("%d
    ",(tp-ans[i])*2);
        }
        return 0;
    }
  • 相关阅读:
    Python3.4 多线程
    OSG Win7 + VS2015 编译
    OSG-3.4.0 简要说明(Readme)
    Boost 1.62.0 编译参数
    VS2015 + QT5.7 中文的坑
    C++库编译
    osg学习笔记3 简单几何模型
    Sqlserver 创建账号
    nginx检查报错:nginx: [emerg] "server" directive is not allowed here in
    Linux修改挂载目录名称
  • 原文地址:https://www.cnblogs.com/sbaof/p/3332800.html
Copyright © 2011-2022 走看看