The dream of WEEK 7 C TT

Title description

This night, TT had a sweet dream!

In his dream, TT's wish came true, and he became the leader of Meow Star! There are N commercial cities on the Meow Star, numbered 1 to N, of which City 1 is the city where TT is located, that is, the capital.

There are M directional roads on Meow Star for commercial cities to communicate with each other. However, with the increasing prosperity of Meowstar's business, some roads have become very crowded. While TT was distressed, his magic kitty came up with a solution! TT is pleased to accept and promulgate a new policy for this program.

The specific policy is as follows: mark a positive integer for each commercial city to indicate its prosperity. When each cat walks from one commercial city to another commercial city along the road, TT will charge them (destination prosperity-departure point) Prosperity) ^ 3 tax.

TT intends to test whether this policy is reasonable, so he wants to know how much tax must be paid to travel from the capital to other cities. If the total amount is less than 3 or cannot be reached, please quietly type '?'.

Input

Enter T in the first line, indicating that there are T sets of data. (1 <= T <= 50)

For each set of data, enter N in the first row to indicate the number of points. (1 <= N <= 200)

Enter N integers in the second line, which represents the weight a [i] from 1 to N points. (0 <= a [i] <= 20)

Enter M in the third line to indicate the number of directional roads. (0 <= M <= 100000)

In the next M rows, each row has two integers AB, indicating that there is a directed road from A to B.

Next, an integer Q is given, indicating the number of inquiries. (0 <= Q <= 100000)

Each inquiry gives a P, which means seeking the minimum tax from point 1 to point P.

Output

Each query outputs one line, and if it is unreachable or the tax is less than 3, then output '?'.

Sample Input

2
5
6 7 8 9 10
6
1 2
2 3
3 4
1 5
5 4
4 5
2
4
5
10
1 2 4 4 5 6 7 8 9 10
10
1 2
2 3
3 1
1 4
4 5
5 6
6 7
7 8
8 9
9 10
2
3 10

Sample Output

Case 1:
3
4
Case 2:
?
?

Ideas

The problem requires that 1 to the other point requires the least amount of money, which is equivalent to finding the shortest path from 1 to the other point. But the problem is that there is a negative value in the distance weight between two points. If there is a negative ring in the figure, the distance between the point affected by the negative ring and the source point becomes infinitesimal, and the shortest path may be calculated in the negative ring In the infinite loop, it is necessary to judge whether the point enters the negative loop. Use the spfa algorithm to start searching from city No.1. If you find that the number of edges passing through a certain city exceeds n-1, it means that there is a negative ring. From this point, search for the point affected by the negative ring. mark.

Code

#include <iostream>
#include <queue>
#include <string.h>
#include <cmath>

using namespace std;

const int M = 1e6 + 10;
const int inf = 1e9;
const int N = 200 + 10;
struct Edge {
	int to, next, w;
}e[M];
int vis[N], cnt[N], dis[N], head[N], temp[N];
int n, m, tot, t, a, b, r;
bool flag[N];

void add(int x, int y,int z)
{
	e[++tot].to = y;
	e[tot].w = z;
	e[tot].next = head[x];
	head[x] = tot;
}

void dfs(int s)
{
	flag[s] = true;
	for (int i = head[s]; i; i = e[i].next)
	{
		int u = e[i].to;
		if (!flag[u])
		{
			dfs(u);
		}
	}
}

queue<int> q;

void spfa(int s)
{
	while (q.size())
		q.pop();
	for (int i = 1; i <= n; i++)
		vis[i] = cnt[i] = 0, dis[i] = inf, flag[i] = false;
	dis[s] = 0, vis[s] = 1;
	q.push(s);
	while (q.size())
	{
		int x = q.front();
		q.pop();
		vis[x] = 0;
		for (int i = head[x]; i; i = e[i].next)
		{
			int y = e[i].to;
			if (dis[y] > dis[x] + e[i].w)
			{
				cnt[y] = cnt[x] + 1;
				if (cnt[y] >= n)
				{
					dfs(y);
				}
				dis[y] = dis[x] + e[i].w;
				if (vis[y]==0&&!flag[y])
					vis[y] = 1, q.push(y);
			}
		}
	}
}

int main()
{
	scanf("%d", &t);
	for (int tt = 1; tt <= t; tt++)
	{
		tot = 0;
		memset(temp, 0, sizeof(temp));
		memset(head, 0, sizeof(head));
		scanf("%d", &n);
		for (int i = 1; i <= n; i++)
			scanf("%d", &temp[i]);
		scanf("%d", &m);
		for (int i = 1; i <= m; i++)
		{
			scanf("%d %d", &a, &b);
			int c = pow((temp[b] - temp[a]), 3);
			add(a, b, c);
		}
		spfa(1);
		printf("Case %d:\n", tt);
		scanf("%d", &r);
		for (int i = 1; i <= r; i++)
		{
			int p;
			scanf("%d", &p);
			if (flag[p] || dis[p] < 3 || dis[p] == inf) 
				printf("?\n");
			else 
				printf("%d\n", dis[p]);
		}
	}
	return 0;
}
Published 32 original articles · praised 0 · visits 673

Guess you like

Origin blog.csdn.net/qq_43814559/article/details/105545538
TT