MnZn求助负环(悬一关)
查看原帖
MnZn求助负环(悬一关)
428889
Xile楼主2023/12/16 21:27

一直 85 pts

#include <bits/stdc++.h>

using namespace std;

namespace inout{
	char gc(){
		static char buf[100000], *p1=buf, *p2=buf; 
		return p1 == p2 &&(p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1++; 
	}
//#define getchar gc
	int read() {
		int x = 0, f = 0; char  c = getchar();
		while (!isdigit(c)) f |= (c == '-'), c = getchar();
		while (isdigit(c)) x = (x << 1) + (x << 3) + (c ^ 48), c = getchar();
		return f ? -x : x;
	}
	void write(int x) {
		if (x / 10) write(x / 10);
		putchar(x % 10 ^ 48);
	}
	void print(int x) {
		if (x < 0) x = -x, putchar('-');
		write(x), putchar('\n');
	}
}
using namespace inout;

const int N = 2e3 + 5, M = 3e3 + 5, INF = INT_MAX;
int n, m;

struct Edge{int to, next, val;}edge[M << 1];
int head[N], tot;
void add_edge(int x, int y, int v) {edge[++tot] = {y, head[x], v}, head[x] = tot;}

int dis[N], cnt[N];
bitset<N> vis;
bool spfa() {
	queue<int> q;
	dis[1] = 0, vis[1] = 1;
	q.push(1);
	while (q.size()) {
		int x = q.front();
		q.pop();
		vis[x] = 0;
		for (int i = head[x]; i; i = edge[i].next) {
			int y = edge[i].to;
			if (dis[y] > dis[x] + edge[i].val) {
				dis[y] = dis[x] + edge[i].val;
				cnt[y] = cnt[x] + 1;
				if (cnt[y] >= n) return 1;
				if (vis[y]) continue; 
				vis[y] = 1, q.push(y);
			}
		}
	} 
	return 0;
}

void init() {
	for (int i = 1; i <= n; i++) dis[i] = INF, cnt[i] = vis[i] = 0;
	memset(head, 0, sizeof head);
	tot = 0;
}

signed main() {
	int t = read();
	while (t--) {
		init();
		
		n = read(), m = read();
		for (int i = 1; i <= m; i++) {
			int x = read(), y = read(), z = read();
			add_edge(x, y, z);
			if (z >= 0) add_edge(y, x, z);
		}
		
		spfa() ? puts("YES") : puts("NO");
	}
	return 0;
}
2023/12/16 21:27
加载中...