判断负环——BellMan/SPFA
代码如下
BellMan-Ford
#include <cstdio>
#include <cstring>
#define INF 0x3f3f3f3f
using namespace std;
typedef struct Edge
{
int u,v,w;
}Edge;
Edge eg[5555];
int dis[555],n,tp;
bool BellMan()
{
memset(dis,INF,sizeof(dis));
dis[1] = 0;
int i,j,u,v,w;
for(i = 1; i < n; ++i)
{
for(j = 0; j < tp; ++j)
{
u = eg[j].u;
v = eg[j].v;
w = eg[j].w;
if(dis[u] < INF && dis[u] + w < dis[v])
dis[v] = dis[u] + w;
}
}
for(j = 0; j < tp; ++j)
{
u = eg[j].u;
v = eg[j].v;
w = eg[j].w;
if(dis[u] < INF && dis[u] + w < dis[v])
return 1;
}
return 0;
}
void Add(int u,int v,int w)
{
eg[tp].v = u;
eg[tp].u = v;
eg[tp++].w = w;
}
int main()
{
int t,i,m,u,v,w,k,temp;
scanf("%d",&t);
while(t--)
{
tp = 0;
scanf("%d %d %d",&n,&m,&k);
while(m--)
{
scanf("%d %d %d",&u,&v,&w);
Add(u,v,w);
Add(v,u,w);
}
while(k--)
{
scanf("%d %d %d",&u,&v,&w);
Add(u,v,-w);
}
printf("%s\n",BellMan()? "YES": "NO");
}
return 0;
}
SPFA
#include <cstdio>
#include <queue>
#include <cstring>
using namespace std;
typedef struct Edge
{
int v,w,next;
}Edge;
Edge eg[66666];
int head[555];
int dis[555],n,in[555];
bool vis[555];
int tp;
bool SPFA()
{
memset(dis,-1,sizeof(dis));
memset(vis,0,sizeof(vis));
memset(in,0,sizeof(in));
queue <int> q;
q.push(1);
dis[1] = 0;
int i,u,v,w;
while(!q.empty())
{
u = q.front();
q.pop();
vis[u] = 0;
for(i = head[u]; i != -1; i = eg[i].next)
{
v = eg[i].v;
w = eg[i].w;
if(dis[v] == -1 || dis[v] > dis[u] + w)
{
dis[v] = dis[u] + w;
if(!vis[v])
{
in[v]++;
if(in[v] == n) return 1;
vis[v] = 1;
q.push(v);
}
}
}
}
return 0;
}
void Add(int u,int v,int w)
{
eg[tp].next = head[u];
eg[tp].v = v;
eg[tp].w = w;
head[u] = tp++;
}
int main()
{
int t,i,m,k,w,u,v;
scanf("%d",&t);
while(t--)
{
scanf("%d %d %d",&n,&m,&k);
memset(head,-1,sizeof(head));
while(m--)
{
scanf("%d %d %d",&u,&v,&w);
Add(u,v,w);
Add(v,u,w);
}
while(k--)
{
scanf("%d %d %d",&u,&v,&w);
Add(u,v,-w);
}
printf("%s\n",SPFA()? "YES": "NO");
}
return 0;
}
时间: 2024-12-28 09:15:05