zoukankan      html  css  js  c++  java
  • CSU 1808:地铁(Dijkstra)

    http://acm.csu.edu.cn/csuoj/problemset/problem?pid=1808

    题意:……

    思路:和之前的天梯赛的一题一样,但是简单点。

    没办法直接用点去算。把边看成点去做,规定dis[i]为走完第i条边之后即达到edge[i].v这个点的时候需要的花费。

    点数为2*m。如果用普通的Dijkstra和SPFA会超时,所以用优先队列优化的Dijkstra。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 #define N 100010
     4 typedef long long LL;
     5 const LL INF = 1000000000000000000LL;
     6 struct Edge {
     7     int u, v, nxt, w, c;
     8 } edge[N*2];
     9 struct Node {
    10     LL d; int id;
    11     bool operator < (const Node &rhs) const {
    12         return d > rhs.d;
    13     }
    14 };
    15 int head[N], tot, n, m;
    16 bool vis[N*2];
    17 LL dis[N*2];
    18 
    19 void Add(int u, int v, int w, int id) {
    20     edge[tot] = (Edge) { u, v, head[u], w, id}; head[u] = tot++;
    21     edge[tot] = (Edge) { v, u, head[v], w, id}; head[v] = tot++;
    22 }
    23 
    24 LL Dijkstra() {
    25     for(int i = 0; i < tot; i++) dis[i] = INF;
    26     memset(vis, 0, sizeof(vis));
    27     LL ans = INF;
    28     priority_queue<Node> que;
    29     while(!que.empty()) que.pop();
    30 
    31     for(int i = head[1]; ~i; i = edge[i].nxt)
    32         que.push((Node) {edge[i].w, i}), dis[i] = edge[i].w;
    33     while(!que.empty()) {
    34         Node now = que.top(); que.pop();
    35         int pree = now.id; LL pred = now.d;
    36         if(vis[pree]) continue; vis[pree] = 1;
    37         int u = edge[pree].v;
    38         if(u == n && ans > pred) ans = pred;
    39         for(int i = head[u]; ~i; i = edge[i].nxt) {
    40             int nowe = i;
    41             LL nowd = dis[pree] + edge[nowe].w + abs(edge[nowe].c - edge[pree].c);
    42             if(nowd < dis[nowe] && !vis[nowe]) {
    43                 dis[nowe] = nowd;
    44                 que.push((Node) { nowd, nowe });
    45             }
    46         }
    47     }
    48     return ans;
    49 }
    50 
    51 int main() {
    52     while(~scanf("%d%d", &n, &m)) {
    53         memset(head, -1, sizeof(head)); tot = 0;
    54         for(int i = 1; i <= m; i++) {
    55             int u, v, c, w;
    56             scanf("%d%d%d%d", &u, &v, &c, &w);
    57             Add(u, v, w, c);
    58         }
    59         printf("%lld
    ", Dijkstra());
    60     }
    61     return 0;
    62 }
    63 /*
    64 3 3
    65 1 2 1 1
    66 2 3 2 1
    67 1 3 1 1
    68 3 3
    69 1 2 1 1
    70 2 3 2 1
    71 1 3 1 10
    72 3 2
    73 1 2 1 1
    74 2 3 1 1
    75 */
  • 相关阅读:
    验证字符串空“” 的表达式
    should not this be a private conversation
    【转】你真的了解word-wrap 和 word-break 的区别吗
    To live is to function,that is all there is in living
    [转] windows 上用程序putty使用 ssh自动登录Linux(Ubuntu)
    Vim/gvim容易忘记的快捷键
    [转] Gvim for windows中块选择的方法
    问题集
    web services
    Trouble Shooting
  • 原文地址:https://www.cnblogs.com/fightfordream/p/6816906.html
Copyright © 2011-2022 走看看