[ABC305E] Art Gallery on Graph

有一个很奇怪的做法。

我们令 fif_i 表示从 ii 出发能往外扩散的最多步数,初始时,fai=bif_{a_i} = b_i,接着类似最短路进行松弛,于是我写了一个 SPFA,然后 TLE 了几个点。

接着我们可以用 SLF 优化,然而还是被卡掉了一个点,这里还有一个有趣的优化:我们对于 uu 访问其相邻节点的时候,将访问顺序随机,这样可以使得入队顺序随机,从而降低被卡的可能。

代码:

#include <bits/stdc++.h>
//#include <bits/extc++.h>
using namespace std;
//using namespace __gnu_pbds;
//using namespace __gnu_cxx;
//#define int long long

const int N = 2e5 + 5, MOD = 1e9 + 7; // Remember to change

namespace FastIo
{
	#define QUICKCIN ios::sync_with_stdio(0), cin.tie(0), cout.tie(0)
	int read()
	{
		char ch = getchar();
		int x = 0, f = 1;
		while ((ch < '0' || ch > '9') && ch != '-') ch = getchar();
		while (ch == '-')
		{
			f = -f;
			ch = getchar();
		}
		while (ch >= '0' && ch <= '9')
		{
			x = (x << 1) + (x << 3) + (ch ^ 48);
			ch = getchar();
		}
		return x * f;
	}
	template<class T>
	void write(T x)
	{
		if (x < 0)
		{
			putchar('-');
			x = -x;
		}
		if (x > 9) write(x / 10);
		putchar(x % 10 + '0');
	}
	template<class T>
	void writeln(T x)
	{
		write(x);
		putchar('\n');
	}
}

namespace Graph
{
	vector<int> G[N];
	vector<pair<int, int> > GW[N];
}

namespace Maths
{
	long long qpow(long long x, long long y)
	{
		long long res = 1LL, base = x;
		while (y)
		{
			if (y & 1LL)
			{
				res = res * base % MOD;
			}
			base = base * base % MOD;
			y >>= 1LL;
		}
		return res;
	}
	bool chkbt(int x, int y)
	{
		return (x & (1 << (y - 1)));
	}
	int chgbt1(int x, int y)
	{
		return (x | (1 << (y - 1)));
	}
	int chgbt0(int x, int y)
	{
		return (x & ~(1 << (y - 1)));
	}
	int revbt(int x, int y)
	{
		return (x ^ (1 << (y - 1)));
	}
	int lowbit(int x)
	{
		return x & -x;
	}
	int chg10(int x) // 右边连续1变0
	{
		return (x & (x + 1));
	}
	int chg101(int x) // 右起第一个0变1
	{
		return (x | (x + 1));
	}
	int chg01(int x) // 右边连续0变1
	{
		return (x & (x - 1));
	}
	int rmv1(int x) // 去掉右边连续的 1
	{
		return (x ^ (x + 1)) >> 1;
	}
}

vector<int> G[N];
int h[N], n, m, k;
set<int> ans;
int g[N];
bool isin[N];

void bfs()
{
	memset(g, -1, sizeof g);
	deque<int> q;
	vector<int> v;
	for (int u = 1; u <= n; u++)
	{
		v.emplace_back(u);
	}
	random_shuffle(v.begin(), v.end());
	for (int u : v)
	{
		if (h[u])
		{
			q.push_back(u);
			g[u] = h[u];
			isin[u] = 1;
		}
	}
	while (q.size())
	{
		int u = q.front();
		q.pop_front();
		isin[u] = 0;
		ans.insert(u);
		if (g[u] == 0) continue;
		vector<int> v;
		for (int j : G[u])
		{
			v.emplace_back(j);
		}
		random_shuffle(v.begin(), v.end());
		for (int j : v)
		{
			int d = max(h[j], g[u] - 1);
			if (g[j] < d)
			{
				//printf("%d %d\n", j, g[j]);
				g[j] = d;
				if (!isin[j]) 
				{
					if (!q.empty() && g[j] < g[q.front()]) q.push_back(j);
					else q.push_front(j);
					isin[j] = 1;
				}
				//used[j] = 1;
			}
		}
	}
}

int main()
{
	scanf("%d%d%d", &n, &m, &k);
	for (int i = 1; i <= m; i++)
	{
		int u, v;
		scanf("%d%d", &u, &v);
		G[u].emplace_back(v);
		G[v].emplace_back(u);
	}
	for (int i = 1; i <= k; i++)
	{
		int u, p;
		scanf("%d%d", &u, &p);
		h[u] = p;
		ans.insert(u);
	}
	bfs();
	printf("%d\n", ans.size());
	for (int i : ans) printf("%d ", i);
	return 0;
}
posted @   HappyBobb  阅读(5)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示