一般情况下个人比较喜欢用拓扑排序
也可以用
s
p
f
a
spfa
spfa
P1807 最长路
思路:
拓扑排序求最长路
因为起点固定为
1
1
1,所以需要
d
i
s
dis
dis 数组初始化负无穷,然后
d
i
s
[
1
]
=
0
dis[1]=0
dis[1]=0
适用范围:有向无环图(DAG)
code:
#include<bits/stdc++.h>
#define endl '\n'
#define ll long long
#define ull unsigned long long
#define ld long double
#define all(x) x.begin(), x.end()
#define mem(x, d) memset(x, d, sizeof(x))
#define eps 1e-6
using namespace std;
const int maxn = 1e5 + 9;
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
ll n, m;
struct node{
int next, to, w;
}e[maxn];
int head[maxn], cnt;
int deg[maxn];
ll dis[maxn];
void add(int x, int y, int z){
e[++cnt].to = y;
e[cnt].w = z;
e[cnt].next = head[x];
head[x] = cnt;
}
ll topsort(){
queue <int> q;
for(int i = 1; i <= n; ++i) if(!deg[i]) q.push(i);
for(int i = 1; i <= n; ++i) dis[i] = -1e18;
dis[1] = 0;
while(!q.empty())
{
int x = q.front();q.pop();
for(int i = head[x]; i; i = e[i].next){
int to = e[i].to;
dis[to] = max(dis[to], dis[x] + e[i].w);
deg[to]--;
if(deg[to] == 0) q.push(to);
}
}
return (dis[n] != -1e18 ? dis[n] : -1ll);
}
void work()
{
cin >> n >> m;
for(int i = 1, x, y, z; i <= m; ++i){
cin >> x >> y >> z;
deg[y]++;
add(x, y, z);
}
cout << topsort() << endl;
}
int main()
{
ios::sync_with_stdio(0);
// int TT;cin>>TT;while(TT--)
work();
return 0;
}
s
p
f
a
spfa
spfa
建边时取负边,然后跑最短路,最后对答案取负即可
mem(dis,-0x3f);//此时初始化的值并不是 -inf,不好判断-1的情况
当然也可以直接
f
o
r
for
for 赋值负无穷,直接跑最长路即可
code:
#include<bits/stdc++.h>
#define endl '\n'
#define ll long long
#define ull unsigned long long
#define ld long double
#define all(x) x.begin(), x.end()
#define mem(x, d) memset(x, d, sizeof(x))
#define eps 1e-6
using namespace std;
const int maxn = 2e6 + 9;
const int mod = 1e9 + 7;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
ll n, m;
struct node{
int next, to, w;
}e[maxn];
int head[maxn], cnt;
ll dis[maxn];
bool vis[maxn];
void add(int x, int y, int z){
e[++cnt].to = y;
e[cnt].w = z;
e[cnt].next = head[x];
head[x] = cnt;
}
void spfa(int s){
queue <int> q;
mem(dis, 0x3f);dis[s] = 0;q.push(s);
while(!q.empty()){
int x = q.front();q.pop();
vis[x] = 0;
for(int i = head[x]; i; i = e[i].next){
int to = e[i].to;
if(dis[to] > dis[x] + e[i].w){
dis[to] = dis[x] + e[i].w;
if(!vis[to]){
q.push(to);
vis[to] = 1;
}
}
}
}
}
void work()
{
cin >> n >> m;
for(int i = 1; i <= m; ++i){
int x, y, z;cin >> x >> y >> z;
add(x, y, -z);
}
spfa(1);
cout << (dis[n] == INF ? -1 : -dis[n]);
}
int main()
{
ios::sync_with_stdio(0);
// int TT;cin>>TT;while(TT--)
work();
return 0;
}