题目来源:http://poj.org/problem?id=3259
第一个是Bellman-Ford 、第二个是Floyd-Warshall。
(一)
#include <iostream>
#include<cstring>
#include<cstdio>
using namespace std;
struct edge{
int from,to,cost;
}ed[6005];
int F,N,M,W;
int d[505],num;
bool find_negative_loop();
int main()
{
cin>>F;
while(F--){
scanf("%d%d%d",&N,&M,&W);
int s,e,t;
num=0;
for(int i=1;i<=M;i++){
scanf("%d%d%d",&s,&e,&t);
ed[num].from=s;ed[num].to=e;ed[num].cost=t;
num++;
ed[num].from=e;ed[num].to=s;ed[num].cost=t;
num++;
}
for(int i=1;i<=W;i++){
scanf("%d%d%d",&s,&e,&t);
ed[num].from=s;ed[num].to=e;ed[num].cost=-t;
num++;
}
if(find_negative_loop()) cout<<"YES\n";
else cout<<"NO\n";
}
return 0;
}
//Bellman-Ford
bool find_negative_loop(){
memset(d,0,sizeof(d));
for(int i=1;i<=N;i++){
for(int j=0;j<num;j++){
edge e=ed[j];
if(d[e.to]>d[e.from]+e.cost){
d[e.to]=d[e.from]+e.cost;
//如果不存在负圈,最短路不会经过一个顶点两次,故i最多执行N-1次。
if(i==N) return 1;
}
}
}
return 0;
}
(二)
/*
1
3 3 1
1 2 1
2 1 3
2 3 1
3 1 3
*/
#include <iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int d[505][505];
int F,N,M,W;
bool find_negative_loop();
int main()
{
cin>>F;
while(F--){
scanf("%d%d%d",&N,&M,&W);
memset(d,0x3f3f3f3f,sizeof(d));
for(int i=1;i<=N;i++)
d[i][i]=0;
int s,e,t;
for(int i=0;i<M;i++){
scanf("%d%d%d",&s,&e,&t);
//这里最易出错:(1)双向边(2)不能直接覆盖之前的值
//d[s][e]=d[e][s]=t;
if(t<d[s][e]) d[s][e]=d[e][s]=t;
}
for(int i=0;i<W;i++){
scanf("%d%d%d",&s,&e,&t);;
d[s][e]=-t;
}
if(find_negative_loop()) cout<<"YES\n";
else cout<<"NO\n";
}
return 0;
}
//Warshall-floyd
bool find_negative_loop(){
for(int k=1;k<=N;k++){
for(int i=1;i<=N;i++){
for(int j=1;j<=N;j++){
if(d[i][k]+d[k][j]<d[i][j]) d[i][j]=d[i][k]+d[k][j];
//d[i][j]=(d[i][j]<d[i][k]+d[k][j]?d[i][j]:d[i][k]+d[k][j]);
}
if(d[i][i]<0) return 1;
}
}
return 0;
}