JZYZOJ P1216 虫洞

版权声明:蒟蒻写博客不宜,请随文附上原文链接 https://blog.csdn.net/qq_34493840/article/details/85800021

描述 Description
在一个神秘岛上,有N(1 <= N <= 500)个洞口,标号1…N,它们之间有M (1 <= M <= 2500) 条通道相连。神秘的竟然另外还有W (1 <= W <=200)条传说中的时间虫洞----当到达通道的另一端洞口时,竟然可以比进入的时间要早!
你当然想进行这样的时间之旅,希望从一个洞口s出发,经过几个通道,在比出发早些时候的时间回到洞口s。也许还能碰到自己呢,hehe
根据给定的地图,请判断能否实现这样的愿望。
输入格式 Input Format
第一行:一个整数 F (1 <= F <= 5),表示共有F组数据。(多组数据测试)
每组数据:
第1行:三个整数 N M W
第2至M+1行:每行三个整数 (S, E, T),表示在S与E洞口之间有一个双向通道,通过需要T(0 <= T <= 10,000) 秒。
第M+2至M+W+1行:每行三个整数 (S, E, T),表示在S与E洞口之间有一个单向通道,从S到E可以回到之前T(0 <= T <= 10,000) 秒。
输出格式 Output Format
共1…F行,每行对应一组数据,如果可以实现愿望输出"YES",否则输出"NO".
样例输入 Sample Input
2
3 3 1
1 2 2
1 3 4
2 3 1
3 1 3
3 2 1
1 2 3
2 3 4
3 1 8
样例输出 Sample Output
NO
YES

题解

简单的SPFA判负环 // 感谢石神帮助Orz

CODE:

#include <bits/stdc++.h>
#define MAXX 20000
#define mem(a, b) memset(a, b, sizeof(a))

using namespace std;

inline int read() {
	int s = 0, w = 1; 
	char ch = getchar();
	while(!isdigit(ch)) { if(ch == '-') w = -1; ch = getchar(); }
	while(isdigit(ch)) { s = (s << 1) + (s << 3) + ch - '0'; ch = getchar(); }
	return s * w;
}

int f;
int n, w, m;

struct Edge {
	int next;
	int to;
	int dis;
}edge[MAXX];
int head[MAXX], vis[MAXX], dis[MAXX];
int num_edge = 0;

inline void add(int from, int to, int dis) {
	edge[++num_edge].next = head[from];
	edge[num_edge].to = to;
	edge[num_edge].dis = dis;
	head[from] = num_edge;
}

inline void clean() {
	mem(dis, 0x3f);
	mem(vis, 0);
	mem(head, 0);
	num_edge = 0;
}

bool spfa(int k) {
	vis[k] = 1;
	for(int i = head[k]; i; i = edge[i].next) {
		int v = edge[i].to;
		if(dis[v] > dis[k] + edge[i].dis) {
			dis[v] = dis[k] + edge[i].dis;
			if(vis[v]) return true;
			if(spfa(edge[i].to)) return true;
		}
	}
	vis[k] = 0;
	return false;
}

int main() {
	f = read();
	while(f--) {
		clean();
		n = read(); m = read(); w = read();
		for(int i = 1; i <= m; ++i) {
			int s, e, t;
			s = read(); e = read(); t = read();
			add(s, e, t);
			add(e, s, t);
		}
		for(int i = 1; i <= w; ++i) {
			int s, e, t;
			s = read(); e = read(); t = read();
			add(s, e, -t);
		}
		dis[1] = 0;
		if (spfa(1)) puts("YES");
		else puts("NO");
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_34493840/article/details/85800021