最长路

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;
}
posted @ 2025-03-08 22:38  郭轩均  阅读(27)  评论(0)    收藏  举报