zoukankan      html  css  js  c++  java
  • POJ 3013 Big Christmas Tree(dijkstra算法堆优化模板)

    题意:要建一棵圣诞树,使得总的花费最小。具体规则是:圣诞树是一颗无向树形图,其中,编号为1的节点为根节点,原始图中每条边具有边权(unit):材料的单位价值;每个点也有一个权(weight):点的重量。生成树中,各条边的花费是该边权(unit)* 该边的子树中所有点的重量(weight)和,总的花费则是生成树中所有边的花费之和。
    分析:1、在树中,两点的路径是唯一的
             2、对点u,只有从点u到根结点之间的边会乘以点u的重量
               3、点u的重量不变
     结论:最小总花费=每条边(u,v)*v的子树中各结点的重量
                                 =每个点的重量*从该点到根结点的每条边的单位价值
                                 =每个点*该点到根结点的最短路

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <queue>
     
    using namespace std;
    const int maxn=50000+5;
    const long long INF=0x3f3f3f3f3f;
    int weight[maxn];
    int cnt;
    int head[maxn];
    long long dis[maxn];
    bool vis[maxn];
    int n,m;
    struct Edge
    {
        int to,w,next;
    } edge[maxn<<1];
     
    struct Node
    {
        int u,dis;
        // 此处的dis仅仅是为了使用优先队列:定义优先级
        bool operator <(const Node &a) const
        {
            return dis>a.dis;
            // 当返回true时会更新堆,因此当新元素a的dis小于堆顶元素dis
            // 的时候会返回true,同时会更新堆,故此堆为小顶堆
        }
    };
    void Init()
    {
        cnt=0;
        memset(head,-1,sizeof(head));
        memset(vis,false,sizeof(vis));
        for(int i=0; i<=n; i++)
            dis[i]=INF;
    }
    void addEdge(int u,int v,int w)
    {
        edge[cnt].to=v;
        edge[cnt].w=w;
        edge[cnt].next=head[u];
        head[u]=cnt++;
    }
    void Dijkstra(int s)
    {
        Node now,next;
        priority_queue<Node>q;
        now.dis=0;
        now.u=s;
        dis[s]=0;
        q.push(now);
        while(!q.empty())
        {
            now=q.top();
            q.pop();
            if(vis[now.u])
                continue;
            int u=now.u;
            vis[u]=true;
            for(int i=head[u]; i!=-1; i=edge[i].next)
            {
                int to=edge[i].to;
                //对点v,会有多个dis存在,不过我们只取对顶元素,
                //即dis最小的点v
                if(!vis[to]&&dis[u]+edge[i].w<dis[to])
                {
                    dis[to]=dis[u]+edge[i].w;
                    next.dis=dis[to];
                    next.u=to;
                    q.push(next);
                }
            }
        }
    }
    int main()
    {
        int T;
        cin>>T;
        while(T--)
        {
            cin>>n>>m;
            Init();
            for(int i=1; i<=n; i++)
                scanf("%d",&weight[i]);
            int u,v,w;
            for(int i=1; i<=m; i++)
            {
                scanf("%d%d%d",&u,&v,&w);
                addEdge(u,v,w);
                addEdge(v,u,w);
            }
            Dijkstra(1);
            long long sum=0;
            bool flag=true;
            for(int i=2; i<=n; i++)
            {
                if(dis[i]==INF)
                {
                    flag=false;
                    break;
                }
                sum+=dis[i]*weight[i];
            }
            if(flag)
                cout<<sum<<endl;
            else
                cout<<"No Answer"<<endl;
        }
        return 0;
    }
  • 相关阅读:
    黄聪:让wordpress模板完全整合google AdSense搜索广告
    黄聪:如何用SQL Server内置的存储过程模板对数据库进行备份和恢复
    git使用安装实战
    Redis持久化之大数据服务暂停问题
    redis的那些事
    centos上安装git
    拿什么守护你PHP程序级守护进程的实现与优化
    redis学习资料链接地址汇总
    redis搭建实战记录
    zeromq_传说中最快的消息队列
  • 原文地址:https://www.cnblogs.com/Fy1999/p/9465082.html
Copyright © 2011-2022 走看看