题目大意:n 个点 m 条边 w 个虫洞,m 行三个数表示 a 到 b 花费时间 c,w 行表示 a 到 b 时间逆流 c,即花费时间 -c,虫洞是单向的,问能否回到从前
解题思路:就是判断有无负环,权值能够无限减小。道路是双向的,虫洞是单向的,边的数组大小应该是 m×2+w ,贡献了一发 RE
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<cmath>
#include<string.h>
#include<string>
#include<queue>
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
const int INF = 0x3f3f3f3f;
const int NINF = -INF -1;
const int MAXN = 6000+5;
using namespace std;
int f, n, m, w, tot;
struct Node {
int s, e, t;
}node[MAXN];
double dis[MAXN];
bool bellman() {
for (int i = 0; i <= n; i++)
dis[i] = INF;
dis[0] = 0;
bool flag;
for (int i = 1; i < n; i++) {
flag = false;
for (int j = 0; j < tot; j++)
if (dis[node[j].e] > dis[node[j].s]+node[j].t) {
dis[node[j].e] = dis[node[j].s]+node[j].t;
flag = true;
}
if (!flag) break;
}
for (int i = 0; i < tot; i++)
if (dis[node[i].e] > dis[node[i].s]+node[i].t)
return true;
return false;
}
int main() {
scanf("%d", &f);
while (f--) {
tot = 0;
scanf("%d%d%d", &n, &m, &w);
int a, b, c;
for (int i = 0; i < m; i++) {
scanf("%d%d%d", &a, &b, &c);
node[tot].s = a;
node[tot].e = b;
node[tot++].t = c;
node[tot].s = b;
node[tot].e = a;
node[tot++].t = c;
}
for (int i = m; i < m+w; i++) {
scanf("%d%d%d", &a, &b, &c);
node[tot].s = a;
node[tot].e = b;
node[tot++].t = -c;
}
if (bellman()) printf("YES\n");
else printf("NO\n");
}
return 0;
}