• ZOJ 3946 Highway Project 贪心+最短路


    题目链接:

    http://www.icpc.moe/onlinejudge/showProblem.do?problemCode=3946

    题解:

    用dijkstra跑单元最短路径,如果对于顶点v,存在一系列边(ui,v)使得dis[v]最小(dis[v]表示0到v的距离)。这些边能且只能选一条,那么我们自然应该选cost最小的那个边了。

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<vector>
      5 #include<algorithm>
      6 #include<queue>
      7 using namespace std;
      8 
      9 typedef long long LL;
     10 const int maxn = 1e5 + 10;
     11 
     12 struct Edge {
     13     int ne, u, v, c, d;
     14     Edge(int ne, int u, int v, int d, int c) :ne(ne), u(u), v(v), d(d), c(c) {}
     15     Edge() {}
     16 }egs[maxn * 2];
     17 
     18 struct Heap {
     19     int u, d, c;
     20     Heap(int u, int d) :u(u), d(d) {}
     21     Heap() {}
     22     bool operator < (const Heap& tmp) const {
     23         return d>tmp.d;
     24     }
     25 };
     26 
     27 struct Node {
     28     int u, v, w;
     29     bool operator < (const Node& tmp) const {
     30         return w<tmp.w;
     31     }
     32 }nds[maxn];
     33 
     34 
     35 int head[maxn], tot;
     36 
     37 void addEdge(int u, int v, int d, int c) {
     38     egs[tot] = Edge(head[u], u, v, d, c);
     39     head[u] = tot++;
     40 }
     41 
     42 int n, m;
     43 LL ans_d, ans_c;
     44 
     45 LL dis[maxn];
     46 //pre[u]记录u和前驱节点的那条边的cost
     47 int pre[maxn];
     48 bool done[maxn];
     49 
     50 
     51 void dij() {
     52     for (int i = 0; i<n; i++) {
     53         dis[i] = 2e10;
     54     }
     55     memset(done, false, sizeof(done));
     56     priority_queue<Heap> pq;
     57     dis[0] = 0;
     58     pq.push(Heap(0, 0));
     59     while (!pq.empty()) {
     60         Heap x = pq.top(); pq.pop();
     61         int u = x.u;
     62         if (done[u]) continue;
     63         done[u] = true;
     64         int p = head[u];
     65         while (p != -1) {
     66             Edge &e = egs[p];
     67             if (dis[e.v]>dis[u] + e.d) {
     68                 dis[e.v] = dis[u] + e.d;
     69                 pre[e.v] = e.c;
     70                 pq.push(Heap(e.v, dis[e.v]));
     71             }
     72             else if (dis[e.v] == dis[u] + e.d) {
     73                 //这里贪心选cost最小的边
     74                 if (pre[e.v]>e.c)
     75                     pre[e.v] = e.c;
     76             }
     77             p = e.ne;
     78         }
     79     }
     80     ans_d = 0; ans_c = 0;
     81     for (int i = 0; i<n; i++) {
     82         ans_d += dis[i];
     83     }
     84     for (int i = 1; i<n; i++) {
     85         ans_c += pre[i];
     86     }
     87 }
     88 
     89 void init() {
     90     memset(head, -1, sizeof(head));
     91     memset(pre, -1, sizeof(pre));
     92     tot = 0;
     93 }
     94 
     95 int main() {
     96     //    freopen("data_in.txt","r",stdin);
     97     int tc;
     98     scanf("%d", &tc);
     99     while (tc--) {
    100         scanf("%d%d", &n, &m);
    101         init();
    102         for (int i = 0; i<m; i++) {
    103             int u, v, d, c;
    104             scanf("%d%d%d%d", &u, &v, &d, &c);
    105             addEdge(u, v, d, c);
    106             addEdge(v, u, d, c);
    107         }
    108         dij();
    109         printf("%lld %lld
    ", ans_d, ans_c);
    110     }
    111     return 0;
    112 }
  • 相关阅读:
    20191114PHP验证码
    20191114PHP图像绘制
    20191114PHP文件操作
    20191108添加数组元素操作
    20191108数组组合练习案例
    20191108PHP数组查找练习
    20191107数组排序练习
    20191107PHP创建数组练习
    20191107万年历
    20191101php日期练习
  • 原文地址:https://www.cnblogs.com/fenice/p/5469410.html
Copyright © 2020-2023  润新知