关于这道题目,首先想到的便是SPFA,这个算法的时间复杂度是O(KM),其中K是每个点平均入队次数,M是边数,然鹅,如果有负环,那末K会等于顶点数,时间复杂度为O(NM)。so,这样的时间复杂度和Bellman-Ford的时间复杂度是一样的,所以我们直接用简单的多的Bellman-Ford来做就可以了。
下面上代码:
#include <stdio.h>
inline void Bellman_Ford(int n,int m)
{
int i,j,k,inf=0x3f3f3f3f;
int dis[n+1],u[m+1],v[m+1],w[m+1];
for(i=1;i<=m;i++)
scanf("%d%d%d",&u[i],&v[i],&w[i]);
memsset(dis,0x3f,sizeof((int)*n);
dis[1]=0;
for(k=1;k<n;k++)//Bellman-Ford主体 K次松弛
{
int check=1;
for(i=1;i<=m;i++)//对每条边进行松弛
if(dis[v[i]]>dis[u[i]]+w[i])
dis[v[i]]=dis[u[i]]+w[i],check=0;
if(check) break; //当已经找到到每个点的最短路径后无法松弛了
}
for(i=1;i<=m;i++)//判断负环 按理说如果没负环的话,n次松弛早就找到最短路了
if(dis[v[i]]>dis[u[i]]+w[i])//因为负环的存在,使得环上可以一直松弛
{
printf("YE5\n");
return;
}
printf("N0\n");
}
int main()
{
int t,n,m;
scanf("%d",&t);
while(t--)
scanf("%d%d",&n,&m),Bellman_Ford(n,m);
}