P1807 最长路
Posted feiief
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P1807 最长路相关的知识,希望对你有一定的参考价值。
题目描述
设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。
方法:
topo+dp
需要注意的是会有1到不了的点。可以先筛掉这些点,或者在最开始挑出入度为0的非1点,然后把他们连接的点入度-1。queue最开始只push 1.
Code:
1 #include <bits/stdc++.h> 2 # define LL long long 3 using namespace std; 4 5 const int maxn=1500+10; 6 const int maxm=50000+10; 7 int n,m; 8 int dp[maxn]; 9 struct Edge{ 10 int to, next, val,from; 11 }e[maxm]; 12 int head[maxn]; 13 int en; 14 int ind[maxn]; 15 16 void add(int from, int to, int val){ 17 e[en].from=from; 18 e[en].next=head[from]; 19 e[en].to=to; 20 e[en].val=val; 21 head[from]=en; 22 ++en; 23 } 24 25 int main(){ 26 memset(head,-1,sizeof(head)); 27 scanf("%d %d", &n, &m); 28 for(int i=1;i<=m;++i){ 29 int a,b, c; 30 scanf("%d %d %d", &a, &b, &c); 31 add(a,b,c); 32 ind[b]++; 33 } 34 for(int i=1;i<=n;++i){ 35 if(i!=1 && ind[i]==0){ 36 for(int j=head[i];j!=-1;j=e[j].next){ 37 ind[e[j].to]--; 38 } 39 } 40 dp[i]=-1; 41 } 42 43 dp[1]=0; 44 queue<int> q; 45 q.push(1); 46 while(!q.empty()){ 47 int u=q.front(); 48 q.pop(); 49 for(int i=head[u];i!=-1;i=e[i].next){ 50 int v=e[i].to; 51 --ind[v]; 52 dp[v]=max(dp[v],dp[u]+e[i].val); 53 if(ind[v]==0){ 54 q.push(v); 55 } 56 } 57 } 58 printf("%d", dp[n]); 59 return 0; 60 }
以上是关于P1807 最长路的主要内容,如果未能解决你的问题,请参考以下文章