题目:最长路
思路:
利用拓扑排序寻找关键路径的长度。
注意:
1、有负边。
2、有重边,遇到重边时要用最大的那个边权。
3、判断1、n两点是否连通不是判断是否是连通图,也不是判断是否是强联通图,只要保证这两点连通就可以了。
代码:
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <stack>
#include <queue>
#include <deque>
#include <set>
#include <cstring>
#include <map>
using namespace std;
#define inf -2139062144
int n,m;
int a[1505][1505]= {0};
int g[1505][1505]= {0};
int num[1505]= {0};
bool b[1505]= {0};
int ans[1505]= {0};
bool re[1505]= {0};
int main() {
memset(a,128,sizeof(a));
scanf("%d%d",&n,&m);
for(int i=1; i<=m; i++) {
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
if(a[y][x]==inf) {
++num[y];
}
a[y][x]=max(a[y][x],z);
}
memcpy(g,a,sizeof(a));
memset(ans,128,sizeof(ans));
re[1]=true;
ans[1]=0;
while(true) {
vector<int> c;
for(int i=1; i<=n; i++) {
if(!num[i]&&!b[i]) {
c.push_back(i);
b[i]=true;
if(i==1) continue;
for(int j=1; j<=n; j++) {
if(g[i][j]!=inf) {
ans[i]=max(ans[i],ans[j]+g[i][j]);
if(re[j]) re[i]=true;
}
}
}
}
if(!c.size()) break;
for(int i=0; i<c.size(); i++) {
for(int j=1; j<=n; j++) {
if(a[j][c[i]]!=inf) {
a[j][c[i]]=inf;
num[j]--;
}
}
}
}
if(!re[n]) ans[n]=-1;
printf("%d",ans[n]);
return 0;
}