Light OJ 1074 Extended Traffic 【spfa+dfs标记负环及相连点】

Light OJ 1074 Extended Traffic

题目链接:vjudge传送门

题目大意:
有n个城市,每一个城市有一个拥挤度Ai,从一个城市I到另一个城市J的时间为:(Av−Au)3。问从第一个城市到达第k个城市所花的时间,如果不能到达,或者时间小于3输出?否则输出所花的时间。

具体思路:
因为有负权并且可能存在负环,故spfa求最短路并标记负环,假设存在一个负环,那么负环上的每个点都能不断的更新,不存在最短距离,而这些点也能不断的更新它所连向的点,故把它们也标记为无法到达。

具体代码:

#include
#include
#include
#include
#include
#include
#include
using namespace std;
int const N = 210, M = 1e6+5;
int const INF = 0x3f3f3f3f;
int h[N],d[N],visit[N],cnt_inq[N],crow[N],is_reach[N];
int cnt = 0;	//用于前向星建图
int c,n,m;
struct Node {
     
	int v;
	int w;
	int next;
}e[M];

void add(int u, int v, int w)
{
     
	e[cnt].v = v;
	e[cnt].w = w;
	e[cnt].next = h[u];
	h[u] = cnt++;
}
void dfs(int v)
{
     
	for (int i = h[v]; ~i; i = e[i].next)
	{
     
		int t = e[i].v;
		if (!is_reach[t])continue;
		is_reach[t] = 0;
		dfs(t);
	}
}
void spfa()
{
     
	memset(visit, 0, sizeof(visit));
	memset(d, 0x3f, sizeof(d));
	memset(is_reach, 1, sizeof(is_reach));
	memset(cnt_inq, 0, sizeof(cnt_inq));
	queue<int> q;
	q.push(1);
	d[1] = 0;
	cnt_inq[1]++;
	while (q.size())
	{
     
		int t = q.front();
		q.pop();
		visit[t] = 0;
		if (!is_reach[t])continue;
		for (int i = h[t]; ~i; i = e[i].next)
		{
     
			int v = e[i].v;
			int w = d[t] + e[i].w;
			if (d[v] > w ) {
     
				d[v] = w;
				if (cnt_inq[v] > n) {
     
					dfs(v);	//存在负环,标记负环及其连向的点
					continue;
				}
				if (!visit[v]) {
     
					q.push(v);
					visit[v] = 1;
					cnt_inq[v]++;
				}
			}
		}
	}
}
int main()
{
     
	scanf("%d", &c);
	for (int i = 1; i <= c; i++)
	{
     
		cnt = 0;
		memset(h, -1, sizeof(h));
		scanf("%d", &n);
		for (int j = 1; j <= n; j++) {
     
			scanf("%d", &crow[j]);
		}			
		scanf("%d", &m);
		for (int j = 1; j <= m; j++)
		{
     
			int s, d;
			scanf("%d%d", &s, &d);
			add(s, d, pow(crow[d] - crow[s],3));
		}
		spfa();
		printf("Case %d:\n", i);
		int q;
		scanf("%d", &q);
		while (q--)
		{
     
			int t;
			scanf("%d", &t);
			if (d[t] == INF || d[t] < 3 || !is_reach[t])printf("?\n");	//负环,或者到达不了,或者小于3
			else printf("%d\n", d[t]);
		}
	}
	return 0;
}

你可能感兴趣的:(最短路,OJ题解,bfs,&,dfs)