bzoj 4289 Tax - 最短路

题目传送门

  这是一条通往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 }
posted @ 2018-03-04 11:52  阿波罗2003  阅读(210)  评论(0编辑  收藏  举报