第一次使用bellman-ford,与迪杰斯特拉相比,同样是求单源最短路劲,但是bellman-ford可以求负权最短路。方法就是对边进行松弛操作,这题基本就是算法的实现而已,并没有什么变形。
/*bell-manford and spfa*/
#include<iostream>
#include<vector>
using namespace std;
const int MAXN = 10000;
int dis[MAXN];
typedef struct Edge
{
int u,v;
int wright;
}Edge;
void init(int n)
{
for(int i=1;i!=n+1;++i)
{
dis[i]=MAXN;
}
dis[1]=0;
}
int main()
{
int T;cin>>T;
while(T--)
{
vector<Edge> v1;
int n;cin>>n;int e1,e2,k(0);cin>>e1>>e2;
init(n);
Edge E;v1.push_back(E);
for(vector<Edge>::size_type i=1;i!=e1+1;++i)
{
k++;
int u,v,w;
cin>>u>>v>>w;
E.u=u;E.v=v;E.wright=w;
v1.push_back(E);
k++;
E.u=v;E.v=u;E.wright=w;
v1.push_back(E);
}
for(vector<Edge>::size_type i=1;i!=e2+1;++i)
{
k++;
int u,v,w;
cin>>u>>v>>w;
E.u=u;E.v=v;E.wright=w;
E.wright=-w;
v1.push_back(E);
}
for(vector<Edge>::size_type i=1;i!=n;++i)
{
bool finish = true;
for(vector<Edge>::size_type j=1;j!=k+1;++j)
{
if(dis[v1[j].v]>dis[v1[j].u]+v1[j].wright)
{
dis[v1[j].v]=dis[v1[j].u]+v1[j].wright;
finish=false;
}
}
if(finish)
break;
}
int relax(1);
for(vector<Edge>::size_type i=1;i!=k+1;++i)
{
if(dis[v1[i].v]>dis[v1[i].u]+v1[i].wright)
{
relax=0;
break;
}
}
if(relax==1)
cout<<"NO"<<endl;//输出1表示没有负圈,输出0表示有负圈
else
cout<<"YES"<<endl;
}
return 0;
}