Shichikuji y Red de Energía (análisis + árbol recubridor mínimo)

título

Significado de las preguntas:

    Dado n puntos, de manera que n puntos requieren energía. La activación de ellos de dos maneras: 1, el coste c [i] i es el costo de la electricidad; 2, un punto de excitación seleccionado i, la conexión i, j tal que j electricidad, y los costes para su distancia Manhattan multiplicado por K [i] + k [j]. La obtención de los costes mínimos del programa y con energía.
     1 norte 2000 , 1 X yo 1 0 6 , 1 y i 1 0 6 , 1 c i 1 0 9 , 1 k i 1 0 9 1≤n≤2000,1≤x_i≤10 ^ ^ 6,1≤y_i≤10 6,1≤c_i≤10 ^ ^ 9 9,1≤k_i≤10

análisis:

    Debido a que tanto el punto relacionado, es natural pensar en el lado derecho. Después del análisis se puede esperar que un árbol de expansión mínimo para nuestro método directo para construir una casa súper lado tenía razón i c [i] puede ser. Las relaciones con la gráfica completa algoritmo de Prim, de vuelta a nuestra producción, utilizan una matriz de coste, el coste [i] representa la expansión de costo mínimo que necesito para gastar, y sabemos que este nodo es como se me ocurrió.

#include <iostream>
#include <vector>
using namespace std;

typedef long long ll;

ll g[2005][2005],cost[2005];
int x[2005],y[2005],c[2005],k[2005],vis[2005],from[2005];
vector<int> t;
vector<int> t1,t2;

int main()
{
	//ios::sync_with_stdio(false);
	//cin.tie(0);
	int n;
	cin >> n; 
	for (int i = 1; i <= n; i++)
	{
		cin >> x[i] >> y[i];
		cost[i] = 1e18;
	}
	for (int i = 1; i <= n; i++)
	{
		cin >> c[i];
		g[0][i] = c[i];
	}
	for (int i = 1; i <= n; i++)
	{
		cin >> k[i];
	}
	for (int i = 1; i <= n; i++)
	{
		for (int j = 1; j <= n; j++)
		{
			g[i][j] = (ll)(abs(x[i]-x[j]) + abs(y[i]-y[j])) * (k[i] + k[j]);
		}
	}
	//cout << "asd" << '\n';
	ll ans = 0; 
	int begin;
	cost[0] = 0;
	for (int i = 0; i <= n; i++)
	{
		ll minx = 1e18;
		for (int j = 0; j <= n; j++)
		{
			if( !vis[j] && minx > cost[j] )
			{
				minx = cost[j];
				begin = j;
			}
		}
		ans += minx;
		vis[begin] = 1;
		if( from[begin] != 0 )
		{
			t1.push_back(begin);
			t2.push_back(from[begin]);
		}
		for (int j = 1; j <= n; j++)
		{
			if( vis[j] ) continue;
			if( cost[j] > g[begin][j] && g[begin][j] > 0 )
			{
				from[j] = begin;
				cost[j] = g[begin][j];
			}
		}
	}
	cout << ans << '\n';
	for (int i = 1; i <= n; i++)
	{
		//cout << cost[i] << '\n';
		if( cost[i] == c[i] ) t.push_back(i);
	}
	cout << t.size() << '\n';
	for (int i = 0 ; i < t.size(); i++)
	{
		cout << t[i];
		if( i == t.size() - 1 ) cout << '\n';
		else cout << ' ';
	}
	cout << t1.size() << '\n'; 
	for (int i = 0; i < t1.size(); i++)
	{
		cout << t1[i] << ' ' << t2[i] << '\n';
	}
	return 0;
}

Publicados 132 artículos originales · ganado elogios 6 · vistas 7921

Supongo que te gusta

Origin blog.csdn.net/weixin_44316314/article/details/104953936
Recomendado
Clasificación