SPFA(负环) LightOJ 1074 Extended Traffic

题目传送门

题意:收过路费.如果最后的收费小于3或不能达到,输出‘?‘.否则输出到n点最小的过路费

分析:关键权值可为负,如果碰到负环是,小于3的约束条件不够,那么在得知有负环时,把这个环的点都标记下,DFS实现.

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;

const int N = 2e2 + 5;
const int E = 1e4 + 5;
const int INF = 0x3f3f3f3f;
struct Edge	{
	int v, w, nex;
	Edge()	{}
	Edge(int v, int w, int nex) : v (v), w (w), nex (nex) {}
	bool operator < (const Edge &r) const	{
		return w > r.w;
	}
}edge[E];
int head[N];
int d[N];
int cnt[N];
int a[N];
bool vis[N], vis2[N];
int n, m, e;

void init()	{
	memset (head, -1, sizeof (head));
	e = 0;
}

void add_edge(int u, int v, int w)	{
	edge[e] = Edge (v, w, head[u]);
	head[u] = e++;
}

void DFS(int u)	{
	vis2[u] = true;
	for (int i=head[u]; ~i; i=edge[i].nex)	{
		int v = edge[i].v;
		if (!vis2[v])	{
			DFS (v);
		}
	}
}

void SPFA(int s)	{
	memset (cnt, 0, sizeof (cnt));
	memset (vis, false, sizeof (vis));
	memset (vis2, false, sizeof (vis2));
	memset (d, INF, sizeof (d));
	d[s] = 0;	cnt[s] = 0;	vis[s] = true;
	queue<int> que;	que.push (s);
	while (!que.empty ())	{
		int u = que.front ();	que.pop ();
		vis[u] = false;
		for (int i=head[u]; ~i; i=edge[i].nex)	{
			int v = edge[i].v, w = edge[i].w;
			if (vis2[v])	continue;
			if (d[v] > d[u] + w)	{
				d[v] = d[u] + w;
				if (!vis[v])	{
					vis[v] = true;	que.push (v);
					if (++cnt[v] > n)	{
						DFS (v);
					}
				}
			}
		}
	}
}

int cal(int i, int j)	{
	int ret = a[i] - a[j];
	ret = ret * ret * ret;
	return ret;
}

int main(void)	{
	int T, cas = 0;	scanf ("%d", &T);
	while (T--)	{
		init ();
		scanf ("%d", &n);
		for (int i=1; i<=n; ++i)	{
			scanf ("%d", &a[i]);
		}
		scanf ("%d", &m);
		for (int u, v, i=1; i<=m; ++i)	{
			scanf ("%d%d", &u, &v);
			add_edge (u, v, cal (v, u));
		}
		SPFA (1);
		int q;	scanf ("%d", &q);
		printf ("Case %d:\n", ++cas);
		while (q--)	{
			int x;	scanf ("%d", &x);
			if (d[x] == INF || d[x] < 3 || vis2[x])	puts ("?");
			else	printf ("%d\n", d[x]);
		}
	}

	return 0;
}

  

时间: 2024-10-14 07:51:41

SPFA(负环) LightOJ 1074 Extended Traffic的相关文章

LightOj 1074 Extended Traffic (spfa+负权环)

题目链接: http://lightoj.com/volume_showproblem.php?problem=1074 题目大意: 有一个大城市有n个十字交叉口,有m条路,城市十分拥挤,因此每一个路都有一个拥挤度,政府就出台了一个政策,对每一条路收取过路费,收取标准为(终点拥挤度 - 起点拥挤度 )3,,问每次询问m,输出1到m的最小花费,如果不能到达或者最小化费小于3的时候输出‘?’. 解题思路: 用spfa.标记负环. 1 #include <cstdio> 2 #include <

(简单) LightOJ 1074 Extended Traffic,SPFA+负环。

Description Dhaka city is getting crowded and noisy day by day. Certain roads always remain blocked in congestion. In order to convince people avoid shortest routes, and hence the crowded roads, to reach destination, the city authority has made a new

LightOJ 1074 Extended Traffic SPFA 消负环

分析:一看就是求最短路,然后用dij,果断错了一发,发现是3次方,有可能会出现负环 然后用spfa判负环,然后标记负环所有可达的点,被标记的点答案都是“?” #include<cstdio> #include<cstring> #include<queue> #include<cstdlib> #include<algorithm> #include<vector> #include<cmath> using namesp

LightOJ 1074 - Extended Traffic 【SPFA】

<题目链接> 题目大意:有n个城市,每一个城市有一个拥挤度Ai,从一个城市I到另一个城市J的时间为:(A(v)-A(u))^3.问从第一个城市到达第k个城市所花的时间,如果不能到达,或者时间小于3输出?否则输出所花的时间. 解题分析: 很明显,此题路段的权值可能为负,所以我们就不能用Dijkstra算法求最短路了.需要注意的是,当点存在负环的时候,就要将负环所能够到达的所有点全部标记,从起点到这些点的最短路是不存在的(因为假设如果存在最短路,那么只要途中在负环上多走几遍,那么重新算得的时间一定

LightOJ 1074 - Extended Traffic 【SPFA】(经典)

题目大意:有n个城市,每一个城市有一个拥挤度Ai,从一个城市I到另一个城市J的时间为:(A(v)-A(u))^3.问从第一个城市到达第k个城市所花的时间,如果不能到达,或者时间小于3输出?否则输出所花的时间. 解题分析: 很明显,此题路段的权值可能为负,所以我们就不能用Dijkstra算法求最短路了.需要注意的是,当点存在负环的时候,就要将负环所能够到达的所有点全部标记,从起点到这些点的最短路是不存在的(因为假设如果存在最短路,那么只要途中在负环上多走几遍,那么重新算得的时间一定会变少,所以不存

ACM: POJ 3259 Wormholes - SPFA负环判定

POJ 3259 Wormholes Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu Description While exploring his many farms, Farmer John has discovered a number of amazing wormholes. A wormhole is very peculiar because it is a one-way pa

UVA11090 Going in Cycle!! [spfa负环]

https://vjudge.net/problem/UVA-11090 平均权值最小的回路 为后面的做个铺垫 二分最小值,每条边权减去他,有负环说明有的回路平均权值小于他 spfa求负环的时候可以先把所有点加到队列里,d[i]=0 #include <iostream> #include <cstdio> #include <algorithm> #include <cstring> using namespace std; const int N=55;

【日常学习】【SPFA负环+数组模拟链表实现】codevs2645 Spore题解

之前刚刚写了一道"香甜的黄油",是USACO的经典题目了.那道题用SPFA怎么找都过不了,看着别人的PAS轻松过各种拙计.黄学长说最佳方案应当是堆优化的dij,我还没有血,等学了那个之后再写黄油题解吧. 题目: 题目描述 Description 在星系1 的某颗美丽的行星之上.某陈将去标号为N 的星系,从星系g1 到达g2,某陈需要花费c1 的代价[主要是燃料,另外还有与沿途Grox 的势力作战的花费],c1 小于0 则是因为 这样的星系旅行,会给某陈带来收益[来源于物流差价,以及一些

Vijos1053 Easy sssp[spfa 负环]

描述 输入数据给出一个有N(2 <= N <= 1,000)个节点,M(M <= 100,000)条边的带权有向图. 要求你写一个程序, 判断这个有向图中是否存在负权回路. 如果从一个点沿着某条路径出发, 又回到了自己, 而且所经过的边上的权和小于0, 就说这条路是一个负权回路.如果存在负权回路, 只输出一行-1;如果不存在负权回路, 再求出一个点S(1 <= S <= N)到每个点的最短路的长度. 约定: S到S的距离为0, 如果S与这个点不连通, 则输出NoPath. 格