分层图WA#4
查看原帖
分层图WA#4
648765
hnaf楼主2022/10/31 11:43
#include<iostream>
#include<vector>
#include<utility>
#include<queue>
#include<algorithm>
#include<cstring>
#include<cstdio>
#define v Next.first
#define w Next.second
#define INF 1000000
#define reg register
#define Maxn 2510<<2
using namespace std;
typedef long long ll;

ll val[Maxn >> 2];
int d[Maxn >> 2][Maxn >> 2];
ll ans = 0, dis[Maxn];
bool vis[Maxn];
int f[Maxn];
int pre[Maxn], n, m, k;
vector<pair<int, ll>> e[Maxn];
vector<int> G[Maxn >> 2];
inline ll read()
{
	reg ll x = 0;
	reg char c = getchar();
	while (!isdigit(c))
		c = getchar();
	while (isdigit(c))
	{
		x = (x << 3) + (x << 1) + (c ^ 48);
		c = getchar();
	}
	return x;
}

void dk(int s)
{
	priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> Q;
	fill(vis, vis + n + 1,false);
	fill(dis, dis + n + 1, INF);
	dis[s] = 0;
	Q.emplace(make_pair(0, s));
	while (!Q.empty())
	{
		int u = Q.top().second;
		Q.pop();
		if (vis[u]) continue;
		vis[u] = true;
		if (dis[u] >k) continue;
		for(auto x:G[u])
			if (dis[u] + 1 < dis[x])
			{
				dis[x] = dis[u] + 1;
				vis[x] = false;
				Q.emplace(make_pair(dis[x], x));
			}
	}
	for (int i = 1; i <= n; i++)
		d[s][i] = dis[i]-1;
}
void djskstra()
{
	for (reg int j = 0; j <= n << 1; j += n)
		for (reg int i = 2 + j; i <= n + j; i++)
		{
			if (dis[i] == INF) continue;
			//printf("%d\n", dis[i]);
			for (auto Next : e[i])
			{
				if (dis[i] + w <= dis[v])
				{
					int u = i;
					bool flag = true;
					while (u != 1)
					{
						if (f[u] == f[v])
						{
							flag = false;
							break;
						}
						u = pre[u];
					}
					if (flag)
					{
						pre[v] = i;
						dis[v] = dis[i] + w;
					}
				}
			}
		}
}

void init()
{
	cin >> n >> m >> k;
	for (int i = 2; i <= n; i++)
		cin >> val[i];
	int x, y;
	for (reg int i = 1; i <= n; i++)
		for (int j = 1; j <= n; j++)
			d[i][j] = INF;
	for (reg int i = 1; i <= m; i++)
	{
		x = read(), y = read();
		G[x].emplace_back(y);
		G[y].emplace_back(x);
		//	d[x][y] = d[y][x] = 1;
	}
	/*for (reg int i = 1; i <= n; i++)
		for (reg int j = 1; j <= n; j++)
			d[i][j]--;
			*/
}
int main()
{
	//FILE* fin;
	//freopen_s(&fin, "holiday3.in", "r", stdin);
	init();
	//if (k) Floyd();
	for (int i = 1; i <= n; i++)
	{
		dk(i);
	}
	fill(dis, dis + (Maxn), INF);
	for (int i = 2; i <= n; i++)
	{
		if (d[1][i] > k)
			vis[i] = true;
		else
		{
			dis[i] = -val[i];
			pre[i] = 1;
		}
	}
	for (int i = 1; i <= n; i++)
		f[i] = f[i + n] = f[i + 2 * n] = f[i + 3 * n] = i;

	for (int i = 2; i <= n; i++)
		for (int j = 2; j <= n; j++)
		{
			if (i == j) continue;
			if (d[i][j] <= k)
			{
				for (int y = d[1][i] <= k ? 1 : 2; y <= 3; y++)
					e[i + y * n - n].emplace_back(make_pair(j + y * n, -val[j]));
			}
		}
	djskstra();
	for (int i = 2; i <= n; i++)
	{
		if (d[1][i] > k) continue;
		ans = max(ans, -dis[i + 3 * n]);
	}
	cout << ans;
	return 0;
}

堆优化dk求连通性在#4寄了,求调。Orz

2022/10/31 11:43
加载中...