zoukankan      html  css  js  c++  java
  • POJ 3013最短路变形....

    DES:计算输的最小费用。如果不能构成树。输出-1。每条边的费用=所有的子节点权值*这条边的权值。计算第二组样例可以知道树的费用是所有的节点的权值*到根节点的最短路径的长度。

    用dij的邻接矩阵形式直接MLE。编译都通不过。换邻接表的形式。然后。。。。模板。。。

    #include<stdio.h>
    #include<string.h>
    #include<stdio.h>
    #include<iostream>
    #include<queue>
    using namespace std;
    #define maxn 50010
    #define inf 10000000000
    
    int head[maxn];
    int vis[maxn];
    int w[maxn];
    long long dis[maxn];
    int edgeNum;
    
    struct Edge {
       int v, c, nxt;
    }edge[maxn*2];
    
    struct Node {
       int u, dis;
       bool operator < (const Node &a) const {
           return dis > a.dis;
       }
    };
    
    void init() {
       edgeNum = 0;
       for (int i=0; i<maxn; ++i) {
         head[i] = -1;
         dis[i] = inf;
         vis[i] = 0;
       }
    }
    
    void addEdge(int a, int b, int c) {
        edge[edgeNum].v = b;
        edge[edgeNum].c = c;
        edge[edgeNum].nxt = head[a];
        head[a] = edgeNum++;
    }
    
    void Dijkstra(int u) {
        Node temp, now;
        priority_queue<Node>q;
        temp.u = u;
        temp.dis = 0;
        dis[u] = 0;
        q.push(temp);
    
        while(!q.empty()) {
            temp = q.top();
            q.pop();
            if (vis[temp.u]) continue;
                vis[temp.u] = 1;
            for (int i=head[temp.u]; i!=-1; i=edge[i].nxt) {
                int v = edge[i].v;
                if (!vis[v] && dis[v] > dis[temp.u] + edge[i].c)
                {
                    dis[v] = dis[temp.u] + edge[i].c;
                    now.u = v;
                    now.dis = dis[v];
                    q.push(now);
                }
            }
        }
        return;
    }
    
    int main() {
        int t, a, b, c, n, m;
        scanf("%d", &t);
        while(t--) {
            init();
            scanf("%d%d", &n, &m);
            for (int i=0; i<n; ++i) {
                scanf("%d", &w[i]);
            }
            for (int i=0; i<m; ++i) {
                scanf("%d%d%d", &a, &b, &c);
                a--, b--;
                addEdge(a, b, c);
                addEdge(b, a, c);
            }
            Dijkstra(0);
            int i;
            long long ans = 0;
            for (i=0; i<n; ++i) {
              if (dis[i] == inf) {
                  break;
              }
              ans += dis[i] * w[i];
            }
            if (i == n)printf("%lld
    ", ans);
            else printf("No Answer
    ");
        }
        return 0;
    }
    View Code
  • 相关阅读:
    1 Groovy
    HDU
    伸展树整理
    HYSBZ
    markdown语法整理
    HDU
    【JZOJ3085】图的计数【数论】
    【JZOJ3085】图的计数【数论】
    【JZOJ3084】超级变变变【模拟】【规律】
    【JZOJ3084】超级变变变【模拟】【规律】
  • 原文地址:https://www.cnblogs.com/icode-girl/p/4783974.html
Copyright © 2011-2022 走看看