• POJ 3013 Big Christmas Tree(单源最短路径)


    题意:

    圣诞树是一颗无向树形图,其中,编号为1的节点为根节点,原始图中每条边具有边权(unit):材料的单位价值,

    每个点也有一个权(weight):点的重量。生成树中,各个点处的花费是指向该点的边权(unit)* 该点的子树中所有点的重量(weight)和,

    总的花费则是生成树中所有点的花费之和。

    思路:

    1. 关键是把题目转换成单源最短路径,每个点所产生的消耗为:该点的权值 * 根节点到该点的距离;

    2. SPFA 求单源最短路径,输出结果为 1 中的累加。 

    #include <iostream>
    #include <algorithm>
    #include <vector>
    #include <queue>
    using namespace std;
    
    const int MAXN = 50010;
    const __int64 INFS = 0x3FFFFFFF7FFFFFFF;
    
    struct edge {
        int v;
        __int64 cost;
        edge* next;
    } *V[MAXN], ES[MAXN*2];
    
    int EC;
    __int64 d[MAXN], weight[MAXN];
    bool inq[MAXN];
    
    void addedge(int u, int v, int cost) {
        ES[++EC].next = V[u]; 
        V[u] = ES + EC;
        V[u]->v = v, V[u]->cost = cost;
    }
    
    void SPFA(int s, int n) {
        for (int i = 1; i <= n; i++)
            d[i] = INFS, inq[i] = false;
        queue<int> Q;
        Q.push(s);
        d[s] = 0, inq[s] = true;
        while (!Q.empty()) {
            int u = Q.front(); Q.pop();
            inq[u] = false;
            for (edge* e = V[u]; e; e = e->next) {
                if (d[e->v] > d[u] + e->cost) {
                    d[e->v] = d[u] + e->cost;
                    if (!inq[e->v]) { 
                        inq[e->v] = true; Q.push(e->v); 
                    }
                }
            }
        }
    }
    
    int main() {
        int cases;
        scanf("%d", &cases);
        while (cases--) {
            int n, e;
            scanf("%d%d", &n, &e);
            for (int i = 1; i <= n; i++) {
                scanf("%I64d", &weight[i]);
                V[i] = 0;
            }
            EC = 0;
            for (int i = 0; i < e; i++) {
                int u, v;
                __int64 cost;
                scanf("%d%d%I64d", &u, &v, &cost);
                addedge(u, v, cost);
                addedge(v, u, cost);
            }
            SPFA(1, n);
            __int64 ans = 0;
            bool flag = false;
            for (int i = 1; i <= n; i++) {
                ans += weight[i] * d[i];
                if (d[i] == INFS) {
                    flag = true; break;
                }
            }
            if (flag) 
                printf("No Answer\n");
            else 
                printf("%I64d\n", ans);
        }
        return 0;
    }
    -------------------------------------------------------

    kedebug

    Department of Computer Science and Engineering,

    Shanghai Jiao Tong University

    E-mail: kedebug0@gmail.com

    GitHub: http://github.com/kedebug

    -------------------------------------------------------

  • 相关阅读:
    两数之和
    输入一个int型数据,计算出该int型数据在内存中存储时1的个数。
    MySQL事务机制(Transaction)
    JAVA 之 深入理解String类
    MySQL 之 SQL练习
    python常用函数及循环
    python多版本配置pyenv
    ES6语法的简单示例
    学习笔记190—利用matlab求解方程组的解
    学习笔记189—pandas 获取Dataframe元素值的几种方法
  • 原文地址:https://www.cnblogs.com/kedebug/p/3046037.html
Copyright © 2020-2023  润新知