这道题的题意是输入的m行是双向的,接下来的w行是单向的,权值为负数。
思路就是找一个负权回路。
代码:
#include<iostream>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<cstdio>
using namespace std;
#define MAXN 1001
#define INF 0xffffffff
struct node {
int ori;
int fin;
double w;
};
node V[MAXN*5+300];
int all;//表示边的条数
double dis[MAXN];//记录s到格各点的距离。
int n,m,W;
bool bell_man() { //图G ,边集 函数 w ,s为源点
for(int i=1; i<=n; i++) {
dis[i]=INF;
}
for(int i=1; i<n; i++) {
bool flag=false;
for(int j=0; j<all; j++) {
if(dis[V[j].fin]>dis[V[j].ori]+V[j].w) {
dis[V[j].fin]=dis[V[j].ori]+V[j].w;
flag=true;
}
}
if(!flag) {
break;
}
}
for(int j=0; j<all; j++) {
if(dis[V[j].fin]>dis[V[j].ori]+V[j].w) {
return false;
}
}
return true;
}
int main() {
int T;
int a;
int b;
int v;
while(~scanf("%d",&T)) {
while(T--) {
scanf("%d%d%d",&n,&m,&W);
all=0;
for(int i=0; i<m; i++) {
scanf("%d%d%d",&a,&b,&v);
V[all].ori=a;
V[all].fin=b;
V[all].w=v;
all++;
V[all].ori=b;
V[all].fin=a;
V[all].w=v;
all++;
}
for(int i=0; i<W; i++) {
scanf("%d%d%d",&a,&b,&v);
V[all].ori=a;
V[all].fin=b;
V[all].w=-v;
all++;
}
if(bell_man()) {
printf("NO\n");
} else {
printf("YES\n");
}
}
}
return 0;
}