P1807 最长路 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
这道题可以用迪杰斯特拉、bellford、floyd、toposort、bfs(后两个本质上是一样的)。下面我将给出后三者的代码。
//floyd(392ms)做了许多无用功
#include <bits/stdc++.h>
#define MOD 1000000007
#define INF 0x3f3f3f3f
using namespace std;
typedef long long LL;
int n,m;
int f[1600][1600];
int main() {
cin>>n>>m;
//初始化
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++) {
if(i==j) f[i][j]=0;
else f[i][j]=-INF;
}
//输入u到v权值为w
while(m--) {
int u,v,w;
cin>>u>>v>>w;
f[u][v]=max(f[u][v],w);//多条边
}
//floyd
for(int k=1; k<=n; k++)
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
if(f[i][k]!=-INF && f[k][j]!=-INF)//没有这句的话会wa一个点
f[i][j]=max(f[i][j],f[i][k]+f[k][j]);
if(f[1][n]==-INF) cout<<-1;//没连通路
else cout<<f[1][n];
return 0;
}
//toposort(51ms)
#include <bits/stdc++.h>
#define MOD 1000000007
#define INF 0x3f3f3f3f
using namespace std;
typedef long long LL;
int n,m;
int ind[1600],maxn[1600],vis[1600];//入度,距离,标记
//结构体用于将当前起点可以走到的终点和其权值捆绑在一起
struct node {
int from,to,w;
};
vector<node> G[1600];//当前起点所指向的所有终点都与其起点有关
queue<int> q;
void toposort() {
for(int i=1; i<=n; i++)
if(ind[i]==0) q.push(i);
while(!q.empty()) {
int h=q.front();
q.pop();
for(int i=0; i<G[h].size(); i++) {
node j=G[h][i];
//终点的入度值--(topo的规矩)
ind[j.to]--;
if(ind[j.to]==0) q.push(j.to);//入度为0后也算是一个起点了
//起点到该终点已经有路
if(vis[h]) {
//原本已经有一条路了,不过要求最长路,所以更新一下。
if(maxn[j.to]<maxn[h]+j.w) maxn[j.to]=maxn[h]+j.w;
vis[j.to]=1;//标记一下终点
}
}
}
}
int main() {
cin>>n>>m;
for(int i=1; i<=m; i++) {
node now;
cin>>now.from>>now.to>>now.w;
ind[now.to]++;//入度
G[now.from].push_back(now);
}
maxn[n]=-1,vis[1]=1;//初始化到n点为-1
toposort();
cout<<maxn[n];//从1到达n的距离
return 0;
}
//BFS
#include <bits/stdc++.h>
#define MOD 1000000007
#define INF 0x3f3f3f3f
using namespace std;
typedef long long LL;
int n,m;
int f[1600][1600],d[1600];//从u到v的最长路 从1到i的最长路
queue<int> q;
void bfs() {
q.push(1);//起点
d[1]=0;//初始化
while(!q.empty()) {
int h=q.front();
q.pop();
for(int i=1; i<=n; i++) {
//非0且距离较小便可更新
if(f[h][i] && d[i]<d[h]+f[h][i]) {
d[i]=d[h]+f[h][i];
q.push(i);//更新后的终点需要入队,用于后续继续BFS来增加长度
}
}
}
}
int main() {
cin>>n>>m;
memset(d,-1,sizeof(d));//便于输出
for(int i=1; i<=m; i++) {
int u,v,w;
cin>>u>>v>>w;
f[u][v]=max(f[u][v],w);//两点间的最长路
}
bfs();
cout<<d[n];
return 0;
}