El sueño de la SEMANA 7 C TT

Descripción del título

¡Esta noche, TT tuvo un dulce sueño!

En su sueño, el deseo de TT se hizo realidad, ¡y se convirtió en el líder de Meow Star! Hay N ciudades comerciales en el Meow Star, numeradas del 1 al N, de las cuales la Ciudad 1 es la ciudad donde se encuentra TT, es decir, la capital.

Hay M carreteras direccionales en Meow Star para que las ciudades comerciales se comuniquen entre sí. Sin embargo, con la creciente prosperidad del negocio de Meowstar, algunas carreteras se han vuelto muy concurridas. Mientras TT estaba angustiado, su gatito mágico encontró una solución. TT se complace en aceptar y promulgar una nueva política para este programa.

La política específica es la siguiente: marque un número entero positivo para cada ciudad comercial para indicar su prosperidad: cuando cada gato camina de una ciudad comercial a otra a lo largo de la carretera, TT los cobrará (punto de partida de prosperidad-salida) Prosperidad) ^ 3 impuestos.

TT tiene la intención de probar si esta política es razonable, por lo que quiere saber cuánto impuesto debe pagarse para viajar desde la capital a otras ciudades. Si el monto total es inferior a 3 o no se puede alcanzar, escriba en silencio '?'.

Entrada

Ingrese T en la primera línea, indicando que hay T conjuntos de datos. (1 <= T <= 50)

Para cada conjunto de datos, ingrese N en la primera fila para indicar el número de puntos. (1 <= N <= 200)

Ingrese N enteros en la segunda línea, que representa el peso a [i] de 1 a N puntos. (0 <= a [i] <= 20)

Ingrese M en la tercera línea para indicar el número de caminos direccionales. (0 <= M <= 100000)

En las siguientes filas M, cada fila tiene dos enteros AB, lo que indica que hay una carretera dirigida de A a B.

A continuación, se proporciona un entero Q, que indica el número de consultas. (0 <= Q <= 100000)

Cada consulta da una P, lo que significa buscar el impuesto mínimo del punto 1 al punto P.

Salida

Cada consulta genera una línea y, si no se puede acceder o si el impuesto es inferior a 3, genera '?'.

Entrada de muestra

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

Salida de muestra

Caso 1:
3
4
Caso 2
:?
?

Ideas

El problema requiere que 1 al otro punto requiera la menor cantidad de dinero, lo que equivale a encontrar la ruta más corta desde 1 al otro punto. Pero el problema es que hay un valor negativo en el peso de la distancia entre dos puntos. Si hay un anillo negativo en la figura, la distancia entre el punto afectado por el anillo negativo y el punto fuente se vuelve infinitesimal, y la ruta más corta puede calcularse en el anillo negativo. En el bucle infinito, es necesario juzgar si el punto entra en el bucle negativo. Use el algoritmo spfa para comenzar a buscar desde la ciudad No. 1. Si encuentra que el número de bordes que pasan por una ciudad determinada excede n-1, significa que hay un anillo negativo. Desde este punto, busque el punto afectado por el anillo negativo. Todos los puntos alcanzados están marcados. Etiqueta.

Código

#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;
}
32 artículos originales publicados · elogiados 0 · visitas 673

Supongo que te gusta

Origin blog.csdn.net/qq_43814559/article/details/105545538
Recomendado
Clasificación