Bellman-Frod判负环,92pts,Wa#9,求助!!!
查看原帖
Bellman-Frod判负环,92pts,Wa#9,求助!!!
959579
xiaobu_dean楼主2023/11/2 15:03
// Bellman-Ford
// 1.初始化d[s] = 0,d[其他点] = inf
// 2.进行多轮循环,每轮对每一条边尝试进行松弛操作
// 3.当在一轮循环中没有成功的松弛操作时,循环结束
// dijkstra是先找到离源点最近的没有找到最短路的点进行松弛操作
// 而Bellman-Ford则是对所有边都尝试松弛,步骤3跳出
#include <bits/stdc++.h>
using namespace std;

using ll = long long ;
const int N = 6e3 + 50 ;
const int inf = 0x3f3f3f3f;
int n,m,t;
struct edge {
	int to,ne,w;
}edge[N];
int head[N],cnt;
void add(int u,int v,int w) {
	cnt++;
	edge[cnt].to = v;
    edge[cnt].w = w;
    edge[cnt].ne = head[u];
    head[u] = cnt;
}
// 以上为链式前向星模版
int d[N];
bool flag;

bool BellmanFord() {
	for (int i = 0;i <= n; i++) d[i] = inf; // 初始化为无穷大
	d[1] = 0;
    for (int i = 1;i <= n; i++) { // 进行n轮循环
    	flag = false;
    	for (int u = 1;u <= n; u++) { // 对每一条边尝试松弛操作
    		if (d[u] == inf) continue;
    		for (int i = head[u];i;i = edge[i].ne) {
    			int v = edge[i].to;
    			int w = edge[i].w;
    			if (d[v] > d[u] + w) {
    				d[v] = d[u] + w;
    				flag = true; // 标记
    			}
    		}
    	}
    	if (!flag) break; // 当在一轮循环中没有成功的松弛操作时,循环结束
    }
    return flag; // flag = true,说明有负环
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cin >> t; // t组数据
	while (t--) {
		memset(head,0,sizeof head);
		cnt = 0;
		cin >> n >> m;
		for (int i = 1;i <= m; i++) {
			int u,v,w; cin >> u >> v >> w;
            add(u,v,w);
            if (w > 0) add(v,u,w);
		}
		if (BellmanFord()) cout << "YES" <<'\n';
		else cout << "NO" << '\n';
	}
	return 0;
}
2023/11/2 15:03
加载中...