题意:
这一晚,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;
}