1. 程式人生 > >bzoj 4289 Tax - 最短路

bzoj 4289 Tax - 最短路

黑科技 define uil apm for pac err 一個點 return

題目傳送門

  這是一條通往vjudge的神秘通道

  這是一條通往bzoj的神秘通道

題目大意

  如果一條路徑走過的邊依次為$e_{1}, e_{2}, \cdots , e_{k}$,那麽它的長度為$e_{1} + \max (e_{1}, e_{2}) + \max (e_{2}, e_{3}) + \cdots + \max (e_{k - 1}, e_{k}) + e_{k}$,問點$1$到點$n$的最短路。

  顯然需要把狀態記在最後一條邊上。

  然後給一個菊花圖,這個做法就gg了。

  因此考慮一些黑科技。

  可以把邊看成點,然後考慮如何在辺與邊之間快速連邊。

  對於一個點的出邊,可以把它們按照權值排序,大的向比它略小的連一條權值為0的邊,小的向比它略大的連一天權值為它們邊權之差的邊。

  然後原圖中每條邊向它的反向邊連一條邊權相同的邊。

  然後再建兩個虛點,一個起點,向以1為起點的邊連邊,邊權不變。一個終點,以$n$為終點的邊向它連邊。

Code

  1 /**
  2  * bzoj
  3  * Problem#4289
  4  * Accepted
  5  * Time: 3200ms
  6  * Memory: 31292k
  7  */
  8 #include <bits/stdc++.h>
  9
#ifndef WIN32 10 #define Auto "%lld" 11 #else 12 #define Auto "%I64d" 13 #endif 14 using namespace std; 15 typedef bool boolean; 16 17 #define ll long long 18 19 typedef class Edge { 20 public: 21 int end, next, w; 22 23 Edge(int end = 9, int
next = 0, int w = 0):end(end), next(next), w(w) { } 24 }Edge; 25 26 typedef class MapManager { 27 public: 28 int ce; 29 int *h; 30 Edge *es; 31 32 MapManager() { } 33 MapManager(int n, int m):ce(-1) { 34 h = new int[(n + 1)]; 35 es = new Edge[(m + 5)]; 36 memset(h, -1, sizeof(int) * (n + 1)); 37 } 38 39 void addEdge(int u, int v, int w) { 40 es[++ce] = Edge(v, h[u], w); 41 h[u] = ce; 42 // cerr << u << "->" << v << " " << w << endl; 43 } 44 45 Edge& operator [] (int pos) const { 46 return es[pos]; 47 } 48 }MapManager; 49 50 int n, m; 51 Edge *es; 52 vector<int> *dg; 53 MapManager g; 54 55 inline void init() { 56 scanf("%d%d", &n, &m); 57 es = new Edge[(m + 1)]; 58 dg = new vector<int>[(n + 1)]; 59 for (int i = 0; i < m; i++) { 60 scanf("%d%d%d", &es[i].end, &es[i].next, &es[i].w); 61 dg[es[i].end].push_back(i << 1); 62 dg[es[i].next].push_back(i << 1 | 1); 63 } 64 } 65 66 boolean cmp(const int& a, const int& b) { 67 return es[a >> 1].w < es[b >> 1].w; 68 } 69 70 int s, t; 71 72 inline void build() { 73 g = MapManager((m << 1) + 2, m << 3); 74 s = m << 1, t = m << 1 | 1; 75 for (int i = 1; i <= n; i++) { 76 sort(dg[i].begin(), dg[i].end(), cmp); 77 for (int j = 1; j < (signed) dg[i].size(); j++) { 78 int u = (j) ? (dg[i][j - 1]) : (-1), v = dg[i][j]; 79 g.addEdge(v, u, 0); 80 g.addEdge(u, v, es[v >> 1].w - es[u >> 1].w); 81 } 82 } 83 84 for (int i = 0; i < (signed) dg[1].size(); i++) 85 g.addEdge(s, dg[1][i], es[dg[1][i] >> 1].w); 86 for (int i = 0; i < (signed) dg[n].size(); i++) 87 g.addEdge(dg[n][i] ^ 1, t, es[dg[n][i] >> 1].w); 88 89 for (int i = 0, w; i < m; i++) { 90 w = es[i].w; 91 g.addEdge(i << 1, i << 1 | 1, w); 92 g.addEdge(i << 1 | 1, i << 1, w); 93 } 94 } 95 96 typedef class Node { 97 public: 98 int p; 99 ll dis; 100 101 Node(int p = 0, ll dis = 0):p(p), dis(dis) { } 102 103 boolean operator < (Node b) const { 104 return dis > b.dis; 105 } 106 }Node; 107 108 ll *f; 109 priority_queue<Node> que; 110 inline ll dijstra() { 111 f = new ll[(m << 1) + 2]; 112 memset(f, 0x3f, sizeof(ll) * ((m << 1) + 2)); 113 que.push(Node(s, f[s] = 0)); 114 while (!que.empty()) { 115 Node e = que.top(); 116 que.pop(); 117 if (e.dis != f[e.p]) continue; 118 for (int i = g.h[e.p]; ~i; i = g[i].next) { 119 Node eu (g[i].end, e.dis + g[i].w); 120 if (eu.dis < f[eu.p]) { 121 f[eu.p] = eu.dis; 122 que.push(eu); 123 } 124 } 125 } 126 return f[t]; 127 } 128 129 inline void solve() { 130 printf(Auto"\n", dijstra()); 131 } 132 133 int main() { 134 init(); 135 build(); 136 solve(); 137 return 0; 138 }

bzoj 4289 Tax - 最短路