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

 1 //拓扑排序求最长路 
 2 #include<bits/stdc++.h>
 3 #include<queue>
 4 using namespace std;
 5 const int INF=0x3f3f3f3f;
 6 const int maxn=1505;
 7 const int maxm=50005;
 8 struct edge{
 9     int dis,to;edge *Nex;
10 }tmp[maxm],*head[maxn];
11 int top=-1;
12 bool v[maxn];//标记数组 把从起点(第一个点)能到的点打标记 确保所求最长路都能从点1到达 
13 inline void add(int x,int y,int z)
14 {
15     tmp[++top].dis=z;tmp[top].to=y;tmp[top].Nex=head[x];head[x]=&tmp[top];
16 }
17 queue<int> q;
18 int du[maxn],last[maxn],n,m;
19 void topo()
20 {
21     int cnt=0;last[n]=-1;v[1]=1;//将到达n的长度初始化为-1  第一个点打标记 
22     for(int i=1;i<=n;++i) if(!du[i]) q.push(i);
23     while(!q.empty())
24     {
25         int p=q.front();q.pop();++cnt;
26         for(edge *i=head[p];i!=NULL;i=i->Nex)
27         {
28             --du[i->to];
29             if(v[p])
30             {
31                 v[i->to]=1;//把第一个点能到的打标记 
32                 last[i->to]=max(last[i->to],last[p]+i->dis);//只有被打过标记才会更新最大值 
33             }
34             if(!du[i->to]) q.push(i->to);
35         }
36     }
37 }
38 int main()
39 {
40     scanf("%d%d",&n,&m);
41     for(int i=1,x,y,z;i<=m;++i) scanf("%d%d%d",&x,&y,&z),add(x,y,z),++du[y];
42     topo();
43     printf("%d",last[n]);
44     return 0;
45 }

 

posted @ 2019-01-24 16:44  宇興  阅读(157)  评论(0编辑  收藏  举报