洛谷P1807 最长路
2025年6月9日大约 2 分钟
洛谷P1807 最长路
题目传送门:https://www.luogu.com.cn/problem/P1807
解法一:拓扑排序
#include <bits/stdc++.h>
using i64 = long long;
using namespace std;
typedef pair<int, int> pii;
constexpr int N = 1505, M = 5e4 + 5;
// mt19937_64 rng(random_device{}());
int n, m;
int ver[M], edge[M], nxt[M], head[N], tot, in[N];
i64 d[N];
void add(int x, int y, int z) {
ver[++tot] = y, edge[tot] = z, nxt[tot] = head[x], head[x] = tot;
}
void topsort() {
queue<int> q;
for (int x = 2; x <= n; ++x) {
if (in[x] == 0) {
q.push(x);
}
}
while (!q.empty()) {
int x = q.front(); q.pop();
for (int i = head[x]; i ; i = nxt[i]) {
int y = ver[i];
if (--in[y] == 0) {
q.push(y);
}
}
}
d[1] = 0;
q.push(1);
while (!q.empty()) {
int x = q.front(); q.pop();
for (int i = head[x]; i ; i = nxt[i]) {
int y = ver[i], z = edge[i];
d[y] = max(d[y], d[x] + z);
if (--in[y] == 0) {
q.push(y);
}
}
}
}
const i64 inf = 1e18;
void solve() {
cin >> n >> m;
fill(d, d + 1 + n, -inf);
for (int i = 0; i < m; ++i) {
int x, y, z;
cin >> x >> y >> z;
add(x, y, z);
++in[y];
}
topsort();
cout << (d[n] ==-inf ? -1 : d[n]) << '\n';
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
#endif
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
solve();
return 0;
}
解法二:边权取负,用spfa跑最短路
#include <bits/stdc++.h>
using i64 = long long;
using namespace std;
typedef pair<int, int> pii;
constexpr int N = 1500 + 5, M = 5e4 + 10;
mt19937_64 rng(random_device{}());
int ver[M], edge[M], nxt[M], head[N], tot, vis[N];
i64 d[N];
void add(int x, int y, int z) {
ver[++tot] = y, edge[tot] = z, nxt[tot] = head[x], head[x] = tot;
}
void spfa(int st) {
memset(d, 0x3f, sizeof d);
queue<int> q;
q.push(st);
vis[st] = 1;
d[st] = 0;
while (!q.empty()) {
int x = q.front(); q.pop();
vis[x] = 0;
for (int i = head[x]; i ; i = nxt[i]) {
int y = ver[i], z = edge[i];
if (d[x] + z < d[y]) {
d[y] = d[x] + z;
if (!vis[y]) {
q.push(y);
vis[y] = 1;
}
}
}
}
}
void solve(){
int n,m;
cin >> n >> m;
for (int i = 0; i < m; ++i) {
int x, y, z;
cin >> x >> y >> z;
add(x, y, -z); // 加负边
}
spfa(1);
if (d[n] == 0x3f3f3f3f3f3f3f3f) {
cout << "-1\n";
} else {
cout << -d[n] << '\n';
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
#endif
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
solve();
return 0;
}