洛谷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 }