zoukankan      html  css  js  c++  java
  • 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
    ",t[i].ans);
        }
        return 0;
    }
    
  • 相关阅读:
    mysql 常用命令
    MAC 升级到10.10(OS X Yosemite)下apache+php的配置问题
    php 第1讲 html介绍 html运行原理①
    php 开山篇
    Sublime Text 2
    java 抽象类和接口整理
    petri 网理论与研究(第一节140915)
    程序员应该读的书
    python logging模块小记
    常见设计模式,单例模式(双重检测锁方式)示例
  • 原文地址:https://www.cnblogs.com/ziyi--caolu/p/3476955.html
Copyright © 2011-2022 走看看