P1807 最长路

最长路

题目描述

G G G 为有 n n n 个顶点的带权有向无环图, G G G 中各顶点的编号为 1 1 1 n n n,请设计算法,计算图 G G G 1 , n 1, n 1,n 间的最长路径。

输入格式

输入的第一行有两个整数,分别代表图的点数 n n n 和边数 m m m

2 2 2 到第 ( m + 1 ) (m + 1) (m+1) 行,每行 3 3 3 个整数 u , v , w u, v, w u,v,w u < v u<v u<v),代表存在一条从 u u u v v v 边权为 w w w 的边。

输出格式

输出一行一个整数,代表 1 1 1 n n n 的最长路。

1 1 1 无法到达 n n n,请输出 − 1 -1 1

样例 #1

样例输入 #1

2 1
1 2 1

样例输出 #1

1

提示

【数据规模与约定】

  • 对于 20 % 20\% 20%的数据, n ≤ 100 n \leq 100 n100 m ≤ 1 0 3 m \leq 10^3 m103
  • 对于 40 % 40\% 40% 的数据, n ≤ 1 0 3 n \leq 10^3 n103 m ≤ 1 0 4 m \leq 10^{4} m104
  • 对于 100 % 100\% 100% 的数据, 1 ≤ n ≤ 1500 1 \leq n \leq 1500 1n1500 0 ≤ m ≤ 5 × 1 0 4 0 \leq m \leq 5 \times 10^4 0m5×104 1 ≤ u , v ≤ n 1 \leq u, v \leq n 1u,vn − 1 0 5 ≤ w ≤ 1 0 5 -10^5 \leq w \leq 10^5 105w105

非常适合不了解求负权路径的同学做一下因为我就是,其实用SPAF就可以了

#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int e[N], ne[N], h[N], idx, w[N], dis[N];
int n, m;
bool st[N];
typedef pair<int, int> PII;
map<PII, int>mp;
void add(int a, int b, int c) {
	e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx++;
}
int spfa() {
	queue<PII> q;
	q.push({ 0,1 });
	dis[1] = 0;
	st[1] = true;
	while (q.size()) {
		PII p = q.front();
		q.pop();
		int t = p.second;
		st[t] = false;
		for (int i = h[t]; i != -1; i = ne[i]) {
			int j = e[i];
			if (dis[j] < dis[t] + w[i]) {
				dis[j] = dis[t] + w[i];
				if (!st[j]) {
					st[j] = true;
					q.push({ dis[j],j });
				}
			}
		}
	}
	if (!dis[n])cout << -1;
	else cout << dis[n];
}
int main() {
	memset(h, -1, sizeof h);
	cin >> n >> m;
	while (m--) {
		int a, b, c;
		cin >> a >> b >> c;
		if (!mp.count({ a, b }) || mp[{a, b}] < c) {
			add(a, b, c);
			mp[{a, b}] = c;
		}
	}
	spfa();

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值