题意是判断一个有向图是否存在负环。Bellman Ford算法,先给出一个我没有优化的版本
//212K 204MS
#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
const int MAXN = 500;
const int MAXM = 2500;
const int MAXW = 200;
struct edge{
int from, to;
int cost;
};
int d[MAXN+5];
edge es[2*MAXM+MAXW+5];
int N, M, W;
int last;
bool judge(){
memset(d, 0, sizeof(d));
for(int i=1; i<=N; i++){
for(int j=1; j<last; j++){
edge e = es[j];
if(d[e.to] > d[e.from] + e.cost){
if(i == N) return 1;
d[e.to] = d[e.from] + e.cost;
}
}
}
return 0;
}
int main(){
int F;
scanf("%d", &F);
while(F--){
scanf("%d%d%d", &N, &M, &W);
last = 1;
int s, e, t;
for(int i=1; i<=M; i++){
scanf("%d%d%d", &s, &e, &t);
es[last].from = s; es[last].to = e; es[last].cost = t; last++;
es[last].from = e; es[last].to = s; es[last].cost = t; last++;
}
for(int i=1; i<=W; i++){
scanf("%d%d%d", &s, &e, &t);
es[last].from = s; es[last].to = e; es[last].cost = -t; last++;
}
if(judge()) puts("YES");
else puts("NO");
}
return 0;
}
双向边只存一次,优化后的代码如下
//184K 125MS
#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
const int MAXN = 500;
const int MAXM = 2500;
const int MAXW = 200;
struct edge{
int from, to;
int cost;
};
int d[MAXN+5];
edge es[MAXM+MAXW+5];
int N, M, W;
int last;
bool judge(){
memset(d, 0, sizeof(d));
for(int i=1; i<=N; i++){
for(int j=1; j<=M; j++){
edge e = es[j];
if(d[e.to] > d[e.from] + e.cost){
if(i == N) return 1;
d[e.to] = d[e.from] + e.cost;
}
if(d[e.from] > d[e.to] + e.cost){
if(i == N) return 1;
d[e.from] = d[e.to] + e.cost;
}
}
for(int j=M+1; j<last; j++){
edge e = es[j];
if(d[e.to] > d[e.from] + e.cost){
if(i == N) return 1;
d[e.to] = d[e.from] + e.cost;
}
}
}
return 0;
}
int main(){
int F;
scanf("%d", &F);
while(F--){
scanf("%d%d%d", &N, &M, &W);
last = 1;
int s, e, t;
for(int i=1; i<=M; i++){
scanf("%d%d%d", &s, &e, &t);
es[last].from = s; es[last].to = e; es[last].cost = t; last++;
}
for(int i=1; i<=W; i++){
scanf("%d%d%d", &s, &e, &t);
es[last].from = s; es[last].to = e; es[last].cost = -t; last++;
}
if(judge()) puts("YES");
else puts("NO");
}
return 0;
}