求助 样例#4输出7 提交代码44分
查看原帖
求助 样例#4输出7 提交代码44分
252015
Shiroko楼主2020/6/30 15:19
#include<bits/stdc++.h>
using namespace std;

const int INF = 1e9;

int n, m, k, r[55], d, dis[55][55], csl[55], ans, len;

double t, t_delta = 0.95;

bool c[55];

int calc()
{
	int res = -1, minn = INT_MAX;
	for (int i = 1; i <= k; i++)
		c[csl[i]] = true;
	for (int i = 0; i < n; i++)
	{
		if (!c[i])
		{
			minn = INT_MAX;
			for (int j = 0; j < n; j++)
				if (i != j && c[j])
					minn = min(minn, dis[i][j]);
			res = max(res, minn);
		}
	}
	for (int i = 1; i <= k; i++)
		c[csl[i]] = false;
	return res;
}

void SA()
{
	t = 5000;
	while (t > 1e-10)
	{
		int i = rand() % k + 1;
		int j = rand() % (len - k) + 1;
		swap(csl[i], csl[j]);
		int energy = calc();
		int delta = energy - ans;
		if (delta < 0)
			ans = energy;
		else if (exp(-delta / t) * RAND_MAX < rand())
			swap(csl[i], csl[j]);
		t *= t_delta;
	}
}

void solve()
{
	ans = calc();
	if (m + k == n)
	{
		cout << 0;
		exit(0);
	}
	for (int i = 1; i <= 100; i++)
		SA();
}

int main()
{
	srand(12345678);
	srand(rand());
	cin >> n >> m >> k;
	for (int i = 0; i < n; i++)
		cin >> r[i];
	for (int i = 0; i < n; i++)
	{
		cin >> d;
		if (!dis[i][r[i]])
		{
			dis[r[i]][i] = d;
			dis[i][r[i]] = d;
		}
	}
	for (int i = 1; i <= m; i++)
	{
		cin >> d;
		c[d] = i;
	}
	for (int i = 0; i < n; i++)
		for (int j = 0; j < n; j++)
		{
			if (i != j && dis[i][j] == 0)
				dis[i][j] = INF;
			if (i == j)
				dis[i][j] = 0;
		}
	for (int i = 0; i < n; i++)
		for (int j = 0; j < n; j++)
			if (i != j)
				for (int k = 0; k < n; k++)
					if (k != i && k != j)
						dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j]);
	for (int i = 0; i < n; i++)
		if (!c[i])
			csl[++len] = i;
	solve();
	cout << ans;
}

思路就是先用 Floyd 处理各个点之间的最短路 然后模拟退火

c数组存的是已经放的城堡 csl数组存的是没放的

2020/6/30 15:19
加载中...