比赛 20160412 评测结果 AAAAAAAAAAAAAAAAEEEA
题目名称 正则表达式 最终得分 85
用户昵称 Fmuckss 运行时间 2.294 s
代码语言 C++ 内存使用 16.53 MiB
提交时间 2016-04-12 10:55:57
显示代码纯文本
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int maxn = 200000+10;

struct edge {
	int to, ne, v;
	edge() {}
	edge(int to_, int ne_, int v_) { to = to_, ne = ne_, v = v_; }
}e[maxn*5];
int head[maxn], tots;

void add_edge(int fr, int to, int v) {
	e[++tots] = edge(to, head[fr], v); head[fr] = tots;
}

class stack{
private:
	int s[maxn];
	int top_;
	bool instack[maxn];
public:
	int top() { 
		return s[top_];
	}
	void pop() {
		instack[s[top_]] = false;
		top_--;
	}
	void push(int num) {
		instack[num] = true;
		s[++top_] = num;
	}
	bool in(int num) {
		return instack[num];
	}
}s;

int dfn[maxn], low[maxn], tot;
int be[maxn], sccn;

void tarjan(int now) {
	int to;
	low[now] = dfn[now] = ++tot;
	s.push(now);
	for(int i = head[now]; i; i = e[i].ne) {
		to = e[i].to;
		if(!dfn[to]){
			tarjan(to);
			low[now] = min(low[to], low[now]);
		}else if(s.in(to)){
			low[now] = min(low[to], low[now]);
		}
	}
	if(dfn[now] == low[now]) {
		int tmp;
		sccn++;
		do {
			tmp = s.top();
			s.pop();
			be[tmp] = sccn;
		}while(tmp != now);
	}
} 

void handle_edge(int now) {
	for(int i = head[now]; i; i = e[i].ne) {
		int to = e[i].to;
		if(be[now] == be[to]) e[i].v = 0;
	}
}

int n, m;

void read() {
	scanf("%d %d", &n, &m);
	int a, b, c;
	for(int i = 1; i <= m; i++) {
		scanf("%d %d %d", &a, &b, &c);
		add_edge(a, b, c);
	}
}

struct pr {
	int now, dis;
	pr() {}
	pr(int now_, int dis_) { now = now_, dis = dis_; } 
	bool operator < (const pr &b) const{
		return dis == b.dis ? now > b.now : dis > b.dis;
	}
};

int dis[maxn];

int dij() {
	memset(dis, 127, sizeof(dis));
	priority_queue<pr> q;
	q.push(pr(1, 0));
	dis[1] = 0;
	int now, ndis;
	while(!q.empty()) {
		now = q.top().now, ndis = q.top().dis;
		q.pop();
		if(ndis > dis[now]) continue;
		for(int i = head[now]; i; i = e[i].ne) {
			int to = e[i].to;
			if(dis[to] > dis[now]+e[i].v) {
				dis[to] = dis[now] + e[i].v;
				q.push(pr(to, dis[to]));
			}
		}
	}
	return dis[n];
}

void solve() {
	for(int i = 1; i <= n; i++) {
		if(!dfn[i]) tarjan(i);
	}
	for(int i = 1; i <= n; i++) {
		handle_edge(i);
	}
	printf("%d", dij());	
}
int main() {
	freopen("regexp.in", "r", stdin);
	freopen("regexp.out", "w", stdout);
	read();
	solve();
	return 0;
}