Extended Traffic LightOJ - 1074(SPFA判负环模板应用)

题意:

这一晚,TT 做了个美梦!

在梦中,TT 的愿望成真了,他成为了喵星的统领!喵星上有 N 个商业城市,编号 1 ~ N,其中 1 号城市是 TT 所在的城市,即首都。

喵星上共有 M 条有向道路供商业城市相互往来。但是随着喵星商业的日渐繁荣,有些道路变得非常拥挤。正在 TT 为之苦恼之时,他的魔法小猫咪提出了一个解决方案!TT 欣然接受并针对该方案颁布了一项新的政策。

具体政策如下:对每一个商业城市标记一个正整数,表示其繁荣程度,当每一只喵沿道路从一个商业城市走到另一个商业城市时,TT 都会收取它们(目的地繁荣程度 - 出发地繁荣程度)^ 3 的税。

TT 打算测试一下这项政策是否合理,因此他想知道从首都出发,走到其他城市至少要交多少的税,如果总金额小于 3 或者无法到达请悄咪咪地打出 '?'

AC代码:

#include <cstdio>
#include <cstring>
#include <queue>
#include <iostream>
#include <fstream>
#include <algorithm>
using namespace std;
const int N = 205, M = 4e5 + 5, INF = 0x3f3f3f3f;
int t, n, m, k, u, v, w, len, p[N], h[N], d[N], cnt[N];//p[i] 记录每个点的权值 
bool vis[N];
struct E {
	int v, w, next;
} e[M];
void add(int u, int v, int w) {
	e[len].v = v;
	e[len].w = w;
	e[len].next = h[u];
	h[u] = len++;	
}
bool spfa() {
	memset(d, 0x3f, sizeof(d));
	memset(cnt, 0, sizeof(cnt));
	memset(vis, false, sizeof(vis));
	d[1] = 0;
 	queue<int> q;
 	q.push(1);
 	while (!q.empty()) {
		int u = q.front();
		q.pop();
		vis[u] = false;
		for (int j = h[u]; j; j = e[j].next) {
			int v = e[j].v;
			int w = e[j].w + d[u];
			if (d[v] > w) {
				d[v] = w;
				cnt[v] = cnt[u] + 1;
				if (cnt[v] >= n) return true;
 				if (!vis[v]) vis[v] = true, q.push(v);
			}
		}
	}
	return false;
} 
int main() {
	int cas = 0;
	scanf("%d", &t);
	while (t--) {
		memset(h, 0, sizeof(h)); len = 1;
		scanf("%d", &n);
		for (int i = 1; i <= n; i++) scanf("%d", &p[i]);
		scanf("%d", &m);
		while (m--) {
			scanf("%d%d", &u, &v);
			w = p[v] - p[u]; //目的地-源点 
			add(u, v, w*w*w);
		}
		spfa();
		printf("Case %d:\n", ++cas);
		scanf("%d", &k);
		while (k--) {
			scanf("%d", &u);
			// 小于3(可能由于负环导致) || 无解  
			if (d[u] < 3 || d[u] > INF / 2) printf("?\n");
			else printf("%d\n", d[u]);
		}
	}
	return 0;
} 

猜你喜欢

转载自blog.csdn.net/Alanrookie/article/details/107922713
今日推荐