题目来自洛谷图论官方题单
以前一直知道有topo排序,但不知道它有什么用,直到今天。topo可以解决和前驱有关的问题,使得该步骤执行时前驱事件已经完成
下面是用topo解决有向图点1到点n最长路径的问题的代码
#include<cstdio>
#include<cstring>
#include<iostream>
#include<queue>
#include<algorithm>
#include<vector>
//使用topo理由,当前点所在路径一定包含前驱;
using namespace std;
int n,m;
const int maxn=5e4+5;
int indu[maxn];
int maxm[maxn];//记忆化,记入前驱到当前的最长路
int vis[maxn];
queue<int>q;
struct edge{
int from;
int to;
int w;
};
vector<edge>G[maxn];
void topotot(){
for(int i=1;i<=n;i++){
if(indu[i]==0){
q.push(i);
}
}
while(!q.empty()){
int v=q.front();
q.pop();
for(int i=0;i<G[v].size();i++){
indu[G[v][i].to]--;
if(vis[v]){
if(maxm[G[v][i].to]<maxm[v]+G[v][i].w){
maxm[G[v][i].to]=maxm[v]+G[v][i].w;
vis[G[v][i].to]=1;
}
}
if(indu[G[v][i].to]==0){//前驱找完了加入队列 ,这样就包含所有情况
q.push(G[v][i].to);
}
}
}
}
int main(){
scanf("%d%d",&n,&m);
edge e;
for(int i=1;i<=m;i++){
scanf("%d%d%d",&e.from,&e.to,&e.w);
indu[e.to]++;
G[e.from].push_back(e);
}
vis[1]=1;
maxm[n]=-1;//初始化 ,如果到不了n点,那么这个值肯定没被操作过
topotot();
printf("%d\n",maxm[n]);
return 0;
}
注意有个标记数组