洛谷P1807 最长路_NOI导刊2010提高(07)

题目描述

设G为有n个顶点的有向无环图,G中各顶点的编号为1到n,且当为G中的一条边时有i < j。设w(i,j)为边的长度,请设计算法,计算图G中<1,n>间的最长路径。

输入格式

输入文件longest.in的第一行有两个整数n和m,表示有n个顶点和m条边,接下来m行中每行输入3个整数a,b,v(表示从a点到b点有条边,边的长度为v)。

输出格式

输出文件longest.out,一个整数,即1到n之间的最长路径.如果1到n之间没连通,输出-1。

题解:因为存在负权边,所以SPFA求最长路即可。

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<queue>
 6 #define maxn 1505
 7 #define INF 0x3ffff
 8 
 9 using namespace std;
10 
11 struct node
12 {
13     int ed,len,nxt;
14 };
15 node edge[50005];
16 int first[maxn],dis[maxn],cnt,n,m;
17 bool vis[maxn];
18 
19 inline void add_edge(int s,int e,int d)
20 {
21     cnt++;
22     edge[cnt].ed=e;
23     edge[cnt].len=d;
24     edge[cnt].nxt=first[s];
25     first[s]=cnt;
26     return;
27 }
28 
29 queue <int> q;
30 inline void spfa(int st)
31 {
32     for(int i=1;i<=n;i++)
33         vis[i]=false,dis[i]=-INF;
34     q.push(st); vis[st]=true;
35     dis[st]=0;
36     while(!q.empty())
37     {
38         int p=q.front(); q.pop();
39         vis[p]=false;
40         for(register int i=first[p];i;i=edge[i].nxt)
41         {
42             int e=edge[i].ed;
43             int d=edge[i].len;
44             int newd=dis[p]+d;
45             if(newd>dis[e])
46             {
47                 dis[e]=newd;
48                 if(!vis[e]) q.push(e);
49             }
50         }
51     }
52     return;
53 }
54 
55 int main()
56 {
57     scanf("%d%d",&n,&m);
58     for(register int i=1;i<=m;i++)
59     {
60         int s,e,d;
61         scanf("%d%d%d",&s,&e,&d);
62         add_edge(s,e,d);
63     }
64     spfa(1);
65     if(dis[n]==-INF) printf("-1\n");
66     else printf("%d",dis[n]);
67     return 0;
68 }

猜你喜欢

转载自www.cnblogs.com/Hoyoak/p/11427477.html