第一种拓扑排序:
//有重边
//对入度为零的点
#include<iostream>
#include<queue>
#include<algorithm>
#include<vector>
#include<memory.h>
#define maxn 1505
using namespace std;
struct edge{
int v,w;
};
vector<edge> s[maxn];
queue<int> q;
int mx[maxn];
int in[maxn];
int n,m;
int main(){
cin>>n>>m;
int x,y,z;
for(int i=1;i<=m;i++){
cin>>x>>y>>z;
for(int j=0;j<s[x].size();j++)
if(y == s[x][j].v){ //去重边
if(s[x][j].w > z) z=s[x][j].w;
}
s[x].push_back((edge){y,z});
in[y]++;
}
//这道题有点不一样,对于其他没有入度的点需要把对应的边去掉
//仔细想想就知道为什么要去掉
for(int i=1;i<=n;i++){
if(in[i] == 0 && i !=1){
//对于非1的入度为零的点进行top排序
for(int j=0;j<s[i].size();j++){
in[s[i][j].v]--;
}
}
}
mx[1]=0;mx[n]=-1;
q.push(1);
while(!q.empty()){
int p=q.front();
q.pop();
for(int i=0;i<s[p].size();i++){
int a=s[p][i].v;
in[a]--;
// if(mx[a]<mx[p]+s[p][i].w) mx[a]=mx[p]+s[p][i].w;
mx[a]=max(mx[a],mx[p]+s[p][i].w);//上一个点的权值加边的权值
if(in[a]==0){
q.push(a);
}
}
}
cout<<mx[n]<<endl;
return 0;
}
第二种:spfa算法
算法具体看:http://keyblog.cn/article-21.html
#include<iostream>
#include<queue>
#include<algorithm>
#include<vector>
#include<memory.h>
#define maxn 1505
using namespace std;
//2、spfa算法:原本是求最短路径
//只需要把权值改为负数,就可以求得最长路径
//考虑重边
#define INF 0x3f3f3f3f
int n,m;
int s[maxn];//最短路径
int t[maxn];//表示是否存在于队列中
queue<int> q;
struct edge{
int v,w;
};
vector<edge> v[maxn];
int main(){
int x,y,z;
cin>>n>>m;
for(int i=1;i<=m;i++){
cin>>x>>y>>z;
z=z*(-1);
// v[x].push_back((edge){y,(-1)*z});
for(int j=0;j<v[x].size();j++)
if(y == v[x][j].v){ //去重边
if(v[x][j].w < z) z=v[x][j].w;
}
v[x].push_back((edge){y,z});
}
s[1]=0;
for(int i=2;i<=n;i++){
s[i]=INF;
}
q.push(1);
while(!q.empty()){
int p=q.front();
q.pop();
t[p]=0;
for(int i=0;i<v[p].size();i++){
int a=v[p][i].v;
s[a] = min(s[a],s[p]+v[p][i].w);
if(t[a] == 0)//如果在队列中不存在
{
q.push(a);
t[a]=1;
}
//遍历队列中是否存在a,如果存在就不入,不存在就入队列
}
}
//
int ans=s[n];
ans=ans*(-1);
if(s[n] == INF){
cout<<-1<<endl;
}
else
cout<<ans<<endl;
return 0;
}