Shichikuji and Power Grid (analysis + minimum spanning tree)

topic

Meaning of the questions:

    Given n points, so that n points required power. Energizing them in two ways: 1, cost c [i] i is the cost of electricity; 2, a selected energization point i, the connection i, j such that j electricity, and costs for their Manhattan distance multiplied by K [i] + k [j]. Obtaining the minimum cost of the program and energized.
     1 n 2000 , 1 x i 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,1≤k_i≤10^9

analysis:

    Because somewhat related point, we naturally think of the right side. After analysis can expect a minimum spanning tree for our direct method to build a super home side was right i c [i] can be. Relations with the complete graph algorithm prim, back to our output, use an array of cost, cost [i] represents the minimum cost expansion i need to spend, and we know that this node is how i came up.

#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;
}

Published 132 original articles · won praise 6 · views 7921

Guess you like

Origin blog.csdn.net/weixin_44316314/article/details/104953936