最长路
题目描述
设 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 n≤100, m ≤ 1 0 3 m \leq 10^3 m≤103。
- 对于 40 % 40\% 40% 的数据, n ≤ 1 0 3 n \leq 10^3 n≤103, m ≤ 1 0 4 m \leq 10^{4} m≤104。
- 对于 100 % 100\% 100% 的数据, 1 ≤ n ≤ 1500 1 \leq n \leq 1500 1≤n≤1500, 0 ≤ m ≤ 5 × 1 0 4 0 \leq m \leq 5 \times 10^4 0≤m≤5×104, 1 ≤ u , v ≤ n 1 \leq u, v \leq n 1≤u,v≤n, − 1 0 5 ≤ w ≤ 1 0 5 -10^5 \leq w \leq 10^5 −105≤w≤105。
#2寄的是因为没有初始化距离为负无穷,会导致负权边取错最大距离
#include<iostream>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;
const int N = 5 * 1e4 + 10;
struct Edge {
int to;
int w;
};
vector<Edge> e[N]; //二维结构体vector存图
int n, m;
int indegree[N]; //入度
int outdegree[N]; //出度
long long dis[N]; //距离数组
void topsort() { //拓扑排序
queue<int>q;
q.push(1);
dis[1] = 0;
while (q.size()) {
int t = q.front();
q.pop();
for (int i = 0; i < e[t].size(); i++) {
int j = e[t][i].to, ww = e[t][i].w;
indegree[j]--;
dis[j] = max(dis[t] + ww, dis[j]); //取最长的边
//每次更新时都判断一下,是dis[j]现存的距离更大,还是dis[t]+w更大,找最大的一条边
if (indegree[j] == 0)q.push(j);
}
}
}
int main() {
cin >> n >> m;
memset(dis,0x80,sizeof dis); //初始化数组为负无穷(0x80)
for (int i = 0; i < m; i++) {
int a; Edge ee;
cin >> a >> ee.to >> ee.w;
e[a].push_back(ee);
indegree[ee.to]++; //记录入度出度
outdegree[a]++;
}
queue<int>q1;
//以下为排除除了1以外的入度为零的点
//注意:必须要找到除1以外的入度为零的点而且把他们扩展出来的点也减少入度,不然会导致有些点在拓扑排序的时候没办法变为入度为零
for (int i = 2; i <= n; i++) {
if (indegree[i] == 0)q1.push(i);
}
while (q1.size()) {
int t = q1.front();
q1.pop();
for (int i = 0; i < e[t].size(); i++) {
int j = e[t][i].to;
indegree[j]--;
if (indegree[j] == 0)q1.push(j);
}
}
topsort(); //拓扑排序
if (dis[n] < -1e5)printf("-1"); //这里写-1e5是因为题目中要求的最小的边权为-1e5
else printf("%d", dis[n]);
return 0;
}