# 大陆争霸[SDOI2010]带限制最短路

【题目描述】

【输入格式】

【输出格式】

---
【思路点拨】

$$\color{red}{Wrong\ Answer\qquad10}$$

【代码实现】

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#define re register
using namespace std;
typedef long long ll;

ll n, m;
ll head[100005], pre[150005], to[150005], val[150005], len;
ll h2[100005], p2[100005], t2[100005], l2, in[100005], ans[100005], dis[100005], tme[100005];
bool vis[100005];

ll ret = 0, flag = 1;
char ch = getchar();
while (ch > '9' || ch < '0') {
if (ch == '-') flag = -1;
ch = getchar();
}
while (ch <= '9' && ch >= '0') {
ret = ret * 10 + ch - '0';
ch = getchar();
}
return ret * flag;
}

void insert(ll u, ll v, ll w) {
to[++len] = v, val[len] = w, pre[len] = head[u], head[u] = len;
}

void insert2(ll u, ll v) {
t2[++l2] = v, p2[l2] = h2[u], h2[u] = l2;
}

void dijkstra() {
for (re int i = 1; i <= n; i++) dis[i] = 0x7fffffff;
dis[1] = tme[1] = ans[1] = 0;
priority_queue< pair<ll, ll> , vector< pair<ll, ll> > , greater< pair<ll, ll> > > q;
q.push(make_pair(0, 1));
while (!q.empty()) {
ll c = q.top().second;
q.pop();
if (vis[c]) continue;
vis[c] = 1;
for (re ll i = head[c]; i != 0; i = pre[i]) {
if (ans[c] + val[i] < dis[to[i]]) {
dis[to[i]] = ans[c] + val[i];
if (!in[to[i]]) {
ans[to[i]] = max(dis[to[i]], tme[to[i]]);
q.push(make_pair(ans[to[i]], to[i]));
}
}
}
for (re ll i = h2[c]; i != 0; i = p2[i]) {
if (in[t2[i]]) {
in[t2[i]]--;
tme[t2[i]] = max(tme[t2[i]], ans[c]);
if (!in[t2[i]]) {
ans[t2[i]] = max(dis[t2[i]], tme[t2[i]]);
q.push(make_pair(ans[t2[i]], t2[i]));
}
}
}
}
}

int main() {
ll u, v, w;
for (re int i = 1; i <= m; i++) {
insert(u, v, w);
}
for (re int i = 1; i <= n; i++) {
for (re int j = 1; j <= in[i]; j++) {
insert2(u, i);
}
}
dijkstra();
printf("%lld\n", ans[n]);
return 0;
} 

(0)
(0)