题目大意:一个农场有很多昆虫洞和一些路,路是双向连通,昆虫洞是单向连通,经过昆虫洞后时间会倒流,但是走路不会,问john是否可以经过一些路和昆虫洞后回到出发点并且时间早于出发时间,即判断是否存在负回路
#include <iostream>
#include <cstdio>
#include <queue>
#include <cstring>
using namespace std;
#define MAXN 501
#define INF 1000000
struct ArcNode //采用邻接表存储
{
int to;
int weight;
ArcNode *next;
};
queue<int> Q;
ArcNode* List[MAXN];
int inq[MAXN];
int dist[MAXN];
int count1[MAXN];
int F,N,M,W;
int S,E,T;
bool SPFA(int src)
{
ArcNode *temp;
int u;
for(int i = 0; i <= N; i++)
{
dist[i] = INF;
inq[i] = 0;
}
dist[src] = 0;
inq[src]++;
Q.push(src);
count1[src]++;
while(!Q.empty())
{
u = Q.front();
Q.pop();
inq[u]--;
if(count1[u] > N) //如果一个节点进出队列的数量超过节点树,说明存在回路
return true;
temp = List[u];
while(temp != NULL)
{
int v = temp->to;
if(dist[v] > dist[u] + temp->weight)
{
dist[v] = dist[u] + temp->weight;
if(!inq[v])
{
Q.push(v);
inq[v]++;
count1[v]++;
}
}
temp = temp->next;
}
}
return false;
}
int main()
{
cin>>F;
while(F--)
{
ArcNode *temp;
cin>>N>>M>>W;
memset(List,0,sizeof(List));
memset(inq,0,sizeof(inq));
memset(count1,0,sizeof(count1));
while(!Q.empty())Q.pop();
for(int i = 0; i < M; i++) //构建双向路
{
cin>>S>>E>>T;
temp = new ArcNode;
temp->to = E;
temp->weight = T;
temp->next = NULL;
if(List[S] == NULL)
{
List[S] = temp;
}
else
{
//temp->next = List[S]->next;
//List[S]->next = temp;
temp->next = List[S];
List[S] = temp;
}
temp = new ArcNode;
temp->to = S;
temp->weight = T;
temp->next = NULL;
if(List[E] == NULL)
{
List[E] = temp;
}
else
{
// temp->next = List[E]->next;
// List[E]->next = temp;
temp->next = List[E];
List[E] = temp;
}
}
for(int i = 0; i < W; i++)
{
cin>>S>>E>>T;
temp = new ArcNode;
temp->to = E;
temp->weight =-T;
temp->next = NULL;
if(List[S] == NULL)
{
List[S] = temp;
}
else
{
//temp->next = List[S]->next;
//List[S]->next = temp;
temp->next = List[S];
List[S] = temp;
}
}
if(SPFA(1) == true)
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
}
return 0;
}
POJ3259 spfa判负回路
最新推荐文章于 2022-08-31 21:05:23 发布
本文介绍了一种基于SPFA算法检测带有时空倒流特性的负权回路的方法,并通过具体的代码实现展示了如何构建图结构及进行遍历判断。

2224

被折叠的 条评论
为什么被折叠?



