hdu3938(最小生成树,推荐)

题意描述:简单的讲就是,给你一张无向图,求有多少条路径使得路径上的花费小于L,这里路径上的花费是这样规定的,a、b两点之间的多条路径中的最长的边最小值!

思路:这题目有多个询问,肯定要用离线输出。思路的话,我们只需要从小到达枚举边的长度,如果两个并查集没有连通,那么联通之后的路径条数就应该是(num[a]*num[b])........

 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int father[10005],num[10005];
struct node
{
    int v1,v2;
    int dis;
}s[50005];
struct node1
{
    int ans;
    int sum;
    int id;
}t[10005];
int cmp(const node a,const node b)
{
    if(a.dis<b.dis)
    return 1;
    else
    return 0;
}
int cmp1(const node1 a,const node1 b)
{
    if(a.sum<b.sum)
    return 1;
    else
    return 0;
}
int cmp2(const node1 a,const node1 b)
{
    if(a.id<b.id)
    return 1;
    else
    return 0;
}
int find(int x)
{
    int root,i=x;
    while(x!=father[x])
    x=father[x];
    root=x;
    x=i;
    while(x!=father[x])
    {
        i=father[x];
        father[x]=root;
        num[root]+=num[x];
        num[x]=0;
        x=i;
    }
    return root;
}
int liantong(int x,int y)
{
    father[x]=y;
    int k=num[y]*num[x];
    num[y]+=num[x];
    num[x]=0;
    return k;
}
int main()
{
    int n,m,q;
    while(scanf("%d%d%d",&n,&m,&q)>0)
    {
        for(int i=0;i<=n;i++)
        {
            father[i]=i;
            num[i]=1;
        }
        int maxn=0;
        for(int i=0;i<m;i++)
        {
            scanf("%d%d%d",&s[i].v1,&s[i].v2,&s[i].dis);
            maxn=s[i].dis;
        }
        sort(s,s+m,cmp);
        //int q;
        //scanf("%d",&q);
        //q=
        for(int i=0;i<q;i++)
        {
            scanf("%d",&t[i].sum);
            t[i].id=i;
        }
        sort(t,t+q,cmp1);
        int j=0;
        for(int i=0;i<q;i++)
        {
            if(i==0)
            t[i].ans=0;
            else
            t[i].ans=t[i-1].ans;
            while(j<m&&t[i].sum>=s[j].dis)
            {
                int tmp=s[j].v1;
                int tmp1=s[j].v2;
                tmp=find(tmp);
                tmp1=find(tmp1);
                if(tmp!=tmp1)
                {
                    t[i].ans+=liantong(tmp,tmp1);
                }
                j++;
            }
        }
        sort(t,t+q,cmp2);
        for(int i=0;i<q;i++)
        printf("%d\n",t[i].ans);
    }
    return 0;
}

 

 

 

posted @ 2013-12-16 16:16  紫忆  阅读(1428)  评论(0编辑  收藏  举报