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