【Dij】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 uu<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

数据范围

  • 对于 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

思路

单源最短路问题板题,本次做这题只是为了重新找回手感,详见我之前写的blog。

代码

#include
#define int long long
using namespace std;
//存图 
int n,m;
int head[1505],nex[50005],cnt = 0;
struct edge{
	int to,w;
}node[50005];
void add(int x,int y,int w) {
	nex[++cnt] = head[x];
	head[x] = cnt;
	node[cnt].to = y;
	node[cnt].w = w;
}
struct point{
	int id,w;
	friend bool operator <(point x,point y) {
		return x.w < y.w;
	}
}; 
priority_queue<point>P;
int ans[1505];
signed main() {
	scanf("%lld %lld",&n,&m);
	for(int i = 2;i <= n;i++) ans[i] = -100000000000;
	for(int i = 1;i <= m;i++) {
		int x,y,z;
		scanf("%lld %lld %lld",&x,&y,&z);
		add(x,y,z);
	} 
	point t;
	t.id = 1,t.w = 0;
	P.push(t);
	while(!P.empty()) {
		t = P.top();
		P.pop();
		for(int i = head[t.id];i;i = nex[i]) {
			if(ans[node[i].to] < ans[t.id] + node[i].w) {
				ans[node[i].to] = ans[t.id] + node[i].w;
				point new_point;
				new_point.id = node[i].to;
				new_point.w = ans[node[i].to];
				P.push(new_point);
			}
		}
	}
	if(ans[n] == -100000000000) printf("-1\n");
	else printf("%lld\n",ans[n]);
    return 0;
}

你可能感兴趣的:(主题库题解,算法,图论,java,1024程序员节,python,数学)