比赛 |
20160412 |
评测结果 |
AAAAAAAAAAAAAAAAAATA |
题目名称 |
正则表达式 |
最终得分 |
95 |
用户昵称 |
Menci |
运行时间 |
2.667 s |
代码语言 |
C++ |
内存使用 |
14.06 MiB |
提交时间 |
2016-04-12 11:45:18 |
显示代码纯文本
#include <cstdio>
#include <climits>
#include <queue>
#include <stack>
const int MAXN = 200000;
const int MAXM = 1000000;
int n, m;
struct Node;
struct Edge;
struct SCC;
struct Node {
Edge *firstEdge, *currentEdge, *inEdge;
SCC *scc;
int dfn, low;
bool inStack, visited, pushed;
int d;
bool q;
} nodes[MAXN];
struct Edge {
Node *from, *to;
Edge *next;
int w;
Edge(Node *from, Node *to, const int w) : from(from), to(to), next(from->firstEdge), w(w) {}
};
struct SCC {
int size;
Node v;
} sccs[MAXN];
inline void addEdge(const int u, const int v, const int w) {
nodes[u].firstEdge = new Edge(&nodes[u], &nodes[v], w);
}
inline int tarjan() {
int timeStamp = 0, count = 0;
for (int i = 0; i < n; i++) {
if (nodes[i].visited) continue;
std::stack<Node *> s, t;
s.push(&nodes[i]);
nodes[i].pushed = true;
while (!s.empty()) {
Node *v = s.top();
if (!v->visited) {
v->visited = true;
v->currentEdge = v->firstEdge;
v->dfn = v->low = timeStamp++;
v->inStack = true;
t.push(v);
}
if (v->currentEdge) {
Edge *&e = v->currentEdge;
if (!e->to->pushed) s.push(e->to), e->to->pushed = true, e->to->inEdge = e;
else if (e->to->inStack) v->low = std::min(v->low, e->to->dfn);
e = e->next;
} else {
if (v->dfn == v->low) {
v->scc = &sccs[count++];
Node *u;
do {
u = t.top();
t.pop();
u->inStack = false;
u->scc = v->scc;
u->scc->size++;
} while (u != v);
}
if (v->inEdge) v->inEdge->from->low = std::min(v->inEdge->from->low, v->low);
s.pop();
}
}
}
return count;
}
inline void contract() {
for (int i = 0; i < n; i++) {
for (Edge *e = nodes[i].firstEdge; e; e = e->next) {
if (e->from->scc != e->to->scc) {
Node *from = &e->from->scc->v, *to = &e->to->scc->v;
from->firstEdge = new Edge(from, to, e->w);
}
}
}
}
inline int bellmanford() {
for (int i = 0; i < n; i++) nodes[i].scc->v.d = INT_MAX;
std::queue<Node *> q;
q.push(&nodes[0].scc->v);
nodes[0].scc->v.d = 0;
while (!q.empty()) {
Node *v = q.front();
q.pop();
v->q = false;
for (Edge *e = v->firstEdge; e; e = e->next) {
if (e->to->d > v->d + e->w) {
e->to->d = v->d + e->w;
if (!e->to->q) e->to->q = true, q.push(e->to);
}
}
}
return nodes[n - 1].scc->v.d;
}
int main() {
freopen("regexp.in", "r", stdin);
freopen("regexp.out", "w", stdout);
scanf("%d %d", &n, &m);
for (int i = 0; i < m; i++) {
int u, v, w;
scanf("%d %d %d", &u, &v, &w), u--, v--;
addEdge(u, v, w);
}
tarjan();
contract();
printf("%d\n", bellmanford());
fclose(stdin);
fclose(stdout);
return 0;
}