LightOJ-1074 Extended Traffic (stack优化Bellman-Ford)

每个junction就是图的一个顶点,边权就是(终点的busyness-起点的busyness) 《LightOJ-1074 Extended Traffic (stack优化Bellman-Ford)》,所以可能会出现负边和负环。要用Bellman-Ford算法求单源最短路。

在这里要注意,本题的图中是包含负环的,对于能求得最短路的点就求,不能到达的点和无最短路的点都要标记出来。

d[i]==inf 表示i处无法到达,d[i]仍是初始值;cnt[i]>=n,代表i点已经n次入栈,如果有最短路,至多n-1次就已经求得最短路,所以这种点就是无最短路的,在spfa时要注意每个点最多入栈n次,这样避免了无限循环,并区分开了有没有最短路的点,因为对于存在最短路的点,最多入了n-1次栈就不会再入了,而不存在的就会再入一次,达到n次。

#include<cstdio>
#include<cstring>
#include<stack>
#include<algorithm>
#define cube(x) ((x)*(x)*(x))
#define maxn 205
#define maxm 20000
#define inf 0x3f3f3f3f
using namespace std;
struct Edge
{
	int  v, w;
} edge[maxm];
int n, b[maxn], m, d[maxn],cnt[maxn];
int head[maxn], nxt[maxm];
bool ins[maxn];
void spfa()
{
	stack<int> s;
	memset(ins + 1, 0, sizeof(bool)*n);
	memset(cnt + 1, 0, sizeof(int)*n);
	memset(d + 1, 0x3f, sizeof(int)*n);
	d[1] = 0;
	ins[1] = true;
	cnt[1] = 1;
	s.push(1);
	while (!s.empty())
	{
		int t=s.top(); s.pop();
		ins[t] = false;
		for (int cur = head[t]; cur != -1; cur = nxt[cur])
		{
			Edge& e = edge[cur];
			if (d[e.v] > d[t] + e.w)
			{
				d[e.v] = d[t] + e.w;
				if (!ins[e.v]&&cnt[e.v]<n)
				{
					ins[e.v] = true;
					s.push(e.v);
					cnt[e.v]++;
				}
			}
		}
	}
}
int main()
{
	int T;
	scanf("%d", &T);
	for (int r = 1; r <= T; r++)
	{
		scanf("%d", &n);
		for (int i = 1; i <= n; i++) scanf("%d", &b[i]);
		scanf("%d", &m);
		memset(head + 1, -1, sizeof(int)*n);
		for (int i = 0,u; i < m; i++)
		{
			scanf("%d%d",&u,&edge[i].v);
			nxt[i] = head[u];
			head[u] = i;
			edge[i].w = cube(b[edge[i].v] - b[u]);
		}
		spfa();
		printf("Case %d:\n", r);
		int q, des;
		scanf("%d", &q);
		for (int i = 0; i < q; i++)
		{
			scanf("%d", &des);
			if (d[des] == inf || d[des] < 3 || cnt[des]>=n) printf("?\n");
			else printf("%d\n", d[des]);
		}
	}
	return 0;
}

 

    原文作者:Bellman - ford算法
    原文地址: https://blog.csdn.net/Accsc/article/details/82631911
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞