#include <iostream> #include <cstdio> #include <queue> #include <cstring> #define maxn 1000000 using namespace std; int n,m; struct Edge{//存边 int next; int to; int dis; }edge[maxn]; queue<int> q;//拓扑排序要用队列 int head[maxn]; int wei[maxn];//点的最大值 int deg[maxn];//点的入度 int a,b,p,num,x; void add(int u,int v,int d){ edge[++num].next=head[u]; edge[num].to=v; edge[num].dis=d; head[u]=num; } int main() { scanf("%d%d",&n,&m); for(int i=1;i<=m;i++){ scanf("%d%d%d",&a,&b,&p); add(a,b,p); deg[b]++; } memset(wei,-0x7f,sizeof(wei));//刚开始的时候,要把所有出了一以外的赋成负无穷,这样保证是从1开始 //这个数据应该是比较水的,没有负边权 //要是有的话,就在每个经过的点上打个标记来判断有没有一条路是到达n的 for(int i=1;i<=n;i++){ if(!deg[i])q.push(i); if(i==1)wei[i]=0; else wei[i]=-maxn; } while(!q.empty()){//拓扑排序 x=q.front(); q.pop(); for(int i=head[x];i;i=edge[i].next){ deg[edge[i].to]--;//入度减1 wei[edge[i].to]=max(wei[edge[i].to],wei[x]+edge[i].dis); /*更新是这样的: 这个点的值最大=max(这个点原来的值,他的前驱节点+连接前驱和他自己的边的值) */ if(deg[edge[i].to]==0){//若入度为0则又入队 q.push(edge[i].to); } } } if(wei[n]<0){//为什么不取等?因为有可能所有边的权值都是0 printf("%d",-1); return 0; } printf("%d",wei[n]); return 0; }