題目鏈接
題目大意
輸入一個圖,有N(1
分析
判斷圖是否存在負環的模板題。
用Bellman-Ford算法,對所有邊進行N-1輪鬆弛,如果之後還能繼續進行鬆弛,則存在負權迴路。時間複雜度O(N*(M+W))
代碼
#include <iostream>
#include <cstdio>
using namespace std;
const int INF=99999999;
const int MAXM=5500;
const int MAXN=510;
struct Edge
{
int u,v,w;
}edge[MAXM];//邊集數組
int dis[MAXN],n,m,t,edgenum;
void Add_Edge(int u,int v,int w)//構造邊集數組
{
edgenum++;
edge[edgenum].u=u;
edge[edgenum].v=v;
edge[edgenum].w=w;
}
bool Bellmen_Ford()
{
for (int i=1;i<=n;i++)
dis[i]=INF;
dis[1]=0;
for (int k=1;k<=n-1;k++)//對所有邊進行N-1輪鬆弛
{
bool flag=false;
for (int i=1;i<=edgenum;i++)
{
int u=edge[i].u;
int v=edge[i].v;
if (dis[v]>dis[u]+edge[i].w)
{
dis[v]=dis[u]+edge[i].w;
flag=true;
}
}
if (!flag) break;//如果鬆弛操作已經沒有更新效果了,可提前退出循環
}
for (int i=1;i<=edgenum;i++)//如果N-1輪鬆弛後還能繼續鬆弛,則存在負環
if (dis[edge[i].v]>dis[edge[i].u]+edge[i].w)
return true;
return false;
}
int main()
{
int F,i,u,v,w;
scanf("%d",&F);
while (F--)
{
scanf("%d%d%d",&n,&m,&t);
edgenum=0;
for (i=1;i<=m;i++)
{
scanf("%d%d%d",&u,&v,&w);
Add_Edge(u,v,w);
Add_Edge(v,u,w);
}
for (i=1;i<=t;i++)
{
scanf("%d%d%d",&u,&v,&w);
Add_Edge(u,v,-w);
}
bool ans=Bellmen_Ford();
if (ans) printf("YES\n");
else printf("NO\n");
}
return 0;
}