最长路
P1807 最长路
题目描述
设 \(G\) 为有 \(n\) 个顶点的带权有向无环图,\(G\) 中各顶点的编号为 \(1\) 到 \(n\),请设计算法,计算图 \(G\) 中 \(1, n\) 间的最长路径。
输入格式
输入的第一行有两个整数,分别代表图的点数 \(n\) 和边数 \(m\)。
第 \(2\) 到第 \((m + 1)\) 行,每行 \(3\) 个整数 \(u, v, w\)(\(u<v\)),代表存在一条从 \(u\) 到 \(v\) 边权为 \(w\) 的边。
输出格式
输出一行一个整数,代表 \(1\) 到 \(n\) 的最长路。
若 \(1\) 无法到达 \(n\),请输出 \(-1\)。
输入输出样例 #1
输入 #1
2 1
1 2 1
输出 #1
1
说明/提示
【数据规模与约定】
- 对于 \(20\%\)的数据,\(n \leq 100\),\(m \leq 10^3\)。
- 对于 \(40\%\) 的数据,\(n \leq 10^3\),\(m \leq 10^{4}\)。
- 对于 \(100\%\) 的数据,\(1 \leq n \leq 1500\),\(0 \leq m \leq 5 \times 10^4\),\(1 \leq u, v \leq n\),\(-10^5 \leq w \leq 10^5\)。
这道题要注意有负权边,所以不能将数组初始化为零,这道题的本质还是spfa,只不过换成了求最大值,全部反着来就行了
#include<iostream>
#include<queue>
#include<vector>
#include<queue>
#include<cstring>
#define int long long
using namespace std;
const int N=1500+5;
struct node{
int id,dis;
};
int d[N];
int vis[N];
vector<node>v[N];
deque<int>q;
signed main(){
int n,m;
cin>>n>>m;
memset(d,-0x3f,sizeof(d));
d[1]=0;
while(m--){
int a,b,c;
cin>>a>>b>>c;
v[a].push_back({b,c});
}
q.push_back(1);
while(!q.empty()){
int t=q.front();
q.pop_front();
//if(vis[t])continue;//不能跳过
vis[t]=0;
for(int i=0;i<v[t].size();i++){
int u=v[t][i].id;
if(d[t]+v[t][i].dis>d[u]){
d[u]=d[t]+v[t][i].dis;
if(!vis[u]){
if(d[u]>d[q.front()])q.push_front(u);
else q.push_back(u);
vis[u]=1;
}
}
}
}
if(d[n]>-1e9)cout<<d[n];
else cout<<-1;
return 0;
}

浙公网安备 33010602011771号