zoukankan      html  css  js  c++  java
  • hdu 5441 Travel 长春网赛

    想到最小生成树的sort+并查集算法,于是可以顺便用并查集维护点所在的连通分量的点的数目(不知道学名是不是这么说),记为poi[v];

    然后当边权限制为f[i].w时,其答案为ww[i]=ww[i-1]-(poi[u]-1)*poi[u]-(poi[v]-1)*poi[v]+(poi[u]+poi[v])*(poi[u]+poi[v]-1);

    之后连通u,v,并将新的poi[u]更新至并查集的树根。这样就相当于用最小生成树+并查集打了个表了,对于询问二分即可

    自己YY的方法,很多地方丑

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int INF=0x7f7f7f7f;
    const int maxm=100008;
    const int maxn=20008;
    struct fuck{
        int u,v,w;
        bool operator<(const fuck &a)    const
        {
            return w<a.w;
        }
    }f[maxm<<1];
    struct shit{
        int u,w;
    }ww[maxm];
    int poi[maxn],uni[maxn];
    int find(int x)
    {
        if(uni[x]!=x)
        {
            uni[x]=find(uni[x]);
            poi[x]=max(poi[x],poi[uni[x]]);
            return uni[x];
        }
        return x;
    }
    int bs(int w,int idx)
    {
        ww[idx].u=INF;
        int left=1,right=idx;
        while(left<right)
        {
            int mid=(right+left)>>1;
            if(ww[mid].u>w)
                right=mid;
            else
                left=mid+1;
        }
        return left-1;
    }
    void update(int x)
    {
        if(uni[x]!=x)
        {
            poi[uni[x]]=max(poi[x],poi[uni[x]]);
            find(uni[x]);
        }
    }
    int main()
    {
        int t,i,j,n,m,q,u,v,w;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d%d%d",&n,&m,&q);
            for(i=1;i<=m;i++)
            {
                scanf("%d%d%d",&u,&v,&w);
                f[i].u=u;f[i].v=v;f[i].w=w;
            }
            sort(f+1,f+1+m);
            for(i=1;i<=n;i++)
            {
                uni[i]=i;
                poi[i]=1;
            }
            int idx=1;
            ww[0].w=0;
            for(i=1;i<=m;i++)
            {
                if(find(f[i].u)!=find(f[i].v))
                {    
                    ww[idx].w=ww[idx-1].w;
                    poi[f[i].u]=max(poi[f[i].u],poi[uni[f[i].u]]);
                    poi[f[i].v]=max(poi[f[i].v],poi[uni[f[i].v]]);
                    uni[uni[f[i].u]]=uni[f[i].v];
                    if(poi[f[i].u]>1)    ww[idx].w-=poi[f[i].u]*(poi[f[i].u]-1);
                    if(poi[f[i].v]>1)    ww[idx].w-=poi[f[i].v]*(poi[f[i].v]-1);
                    poi[f[i].u]+=poi[f[i].v];
                    poi[f[i].v]=poi[f[i].u];
                    update(f[i].u);
                    update(f[i].v);
                    ww[idx].u=f[i].w;
                    ww[idx++].w+=poi[f[i].u]*(poi[f[i].u]-1);
                }
            }
            for(i=1;i<=q;i++)
            {
                scanf("%d",&w);
                int asd=bs(w,idx);
                printf("%d
    ",ww[asd].w);
            }
        }
        return 0;
    }
  • 相关阅读:
    vijos1198:最佳课题选择
    vijos1071:新年趣事之打牌
    vijos1153:猫狗大战
    bzoj3594: [Scoi2014]方伯伯的玉米田
    bzoj2753: [SCOI2012]滑雪与时间胶囊
    bzoj1923: [Sdoi2010]外星千足虫
    bzoj2783: [JLOI2012]树
    bzoj4590: [Shoi2015]自动刷题机
    bzoj4580: [Usaco2016 Open]248
    bzoj4579: [Usaco2016 Open]Closing the Farm
  • 原文地址:https://www.cnblogs.com/bitch1319453/p/4805503.html
Copyright © 2011-2022 走看看