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 最长路的主要内容,如果未能解决你的问题,请参考以下文章

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

P1807 最长路

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

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

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

ACM入门之图论习题