ybtoj 最短路径课堂过关 例题2luogu P3385SPFA(判负环)负环判断 & 模板负环
Posted SSL_ZZL
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ybtoj 最短路径课堂过关 例题2luogu P3385SPFA(判负环)负环判断 & 模板负环相关的知识,希望对你有一定的参考价值。
Link
ybtoj 【最短路径课堂过关】【例题2】负环判断
luogu【P3385】【模板】负环
题面//因为不知道侵不侵权,有账号的直接看转送门就可了
题目大意
给定一个 n 个点的有向图,请求出图中是否存在从顶点 1 出发能到达的负环。
负环的定义是:一条边权之和为负数的回路。
解题思路
有生之年系列,原来就是n打成了m
就是简单的SPFA判负环,统计步数,如果步数超过了点数,也就代表有负环(如果有负环那么SPFA就会一直跑下去)
Code
#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
using namespace std;
struct DT{
int to, s, next;
}a[61000];
queue<int>q;
int T, n, m, x, y, s, num, now;
int dis[41000], v[41000], step[41000], head[41000];
int SPFA() {
memset(dis, 0x7f, sizeof(dis));
memset(v, 0, sizeof(v));
memset(step, 0, sizeof(step));
q.push(1);
v[1] = 1, dis[1] = 0;
while(!q.empty()) {
now = q.front();
q.pop();
v[now] = 0;
for (int i = head[now]; i; i = a[i].next) {
if (dis[a[i].to] > dis[now] + a[i].s) {
dis[a[i].to] = dis[now] + a[i].s;
step[a[i].to] = step[now] + 1; //更新步数
if (step[a[i].to] >= n) //步数超过,表明有负环(就是这里的 n 打成了 m TAT)
return 1;
if (!v[a[i].to]) {
q.push(a[i].to);
v[a[i].to] = 1;
}
}
}
}
return 0;
}
int main() {
scanf("%d", &T);
while(T--) {
scanf("%d %d", &n, &m);
num = 0;
memset(head, 0, sizeof(head));
memset(a, 0, sizeof(a));
for (int i = 1; i <= m; i++) {
scanf("%d %d %d", &x, &y, &s);
a[++num] = (DT){y, s, head[x]};
head[x] = num;
if (s >= 0) {
a[++num] = (DT){x, s, head[y]};
head[y] = num;
}
}
if (SPFA()) printf("YES\\n");
else printf("NO\\n");
}
}
以上是关于ybtoj 最短路径课堂过关 例题2luogu P3385SPFA(判负环)负环判断 & 模板负环的主要内容,如果未能解决你的问题,请参考以下文章