hdu5441 并查集 长春网赛

 对于每次询问的大的值,都是从小的值开始的,那就从小到大处理,省去很多时间,并且秩序遍历一遍m;

这题cin容易超时,scanf明显快很多很多。G++又比C++快;

//这代码scanf400+,cin800+ 并且我交了快10次cin的8次超时
//scanf代码C++400+,G++250+
#include<cstring>
#include<iostream>
#include<algorithm>
#define maxn 20010
using namespace std;
struct node
{
    int l,r,val;
}a[100010];
struct Node
{
    int id;
    int askval;
}fq[5010];
int pa[maxn],n,ans[5010],num[maxn];
bool cmp(node aa,node bb)
{
    return aa.val<bb.val;
}
bool bcmp(Node aa,Node bb)
{
    return aa.askval<bb.askval;
}
int Find(int m)
{
    if(m!=pa[m])
        pa[m]=Find(pa[m]);
    return pa[m];
}
int main()
{
    int i,j,t,m,q;
    cin>>t;
    while(t--)
    {
        scanf("%d%d%d",&n,&m,&q);//写scanf cin容易超时
        for(i=0;i<=n;i++)
        {
            pa[i]=i;
            num[i]=1;
        }
        for(i=1;i<=m;i++)
        {
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            a[i].l=x;
            a[i].r=y;
            a[i].val=z;
        }
        sort(a+1,a+m+1,cmp);
        for(i=0;i<q;i++)
        {
            scanf("%d",&fq[i].askval);
            fq[i].id=i;
        }
        sort(fq,fq+q,bcmp);
        int ret=0;
        j=1;
        for(i=0;i<q;i++)
        {
            for(;j<=m&&a[j].val<=fq[i].askval;j++)
            {
                int fx=Find(a[j].l);
                int fy=Find(a[j].r);
                if(fx!=fy)
                {
                    pa[fy]=fx;
                    ret+=2*num[fx]*num[fy];
                    num[fx]+=num[fy];
                }
            }
            ans[fq[i].id]=ret;
        }
        for(i=0;i<q;i++)
        {
            printf("%d\n",ans[i]);
        }
    }
}

 

posted @ 2015-09-16 16:30  sweat123  阅读(156)  评论(0编辑  收藏  举报