题面:

alt

思路:

先将所有的黑墨水坐标放进优先队列中,并将黑墨水坐标置零表示已走过,用vc数组记录蓝墨水变白时间,优先队列访问当前坐标的上下左右,如果未被访问则加入队列,时间记当前坐标时间+1与vc中两者的最大值,并实时更新max值即可。

代码如下:

#include <bits/stdc++.h>
#define endl '\n'
#define fs first
#define sc second
#define N 10000000
#define PI 3.141592653589793238462643383279L
using namespace std;
typedef long long int ll;
ll dx[4]={0,0,-1,1};
ll dy[4]={-1,1,0,0};
ll n,m,a,b,ans=0;
ll sum(ll c,ll k)
{
	return c*m+k;
}
bool check(ll x,ll y)
{
	return (x>=0&&x<n&&y>=0&&y<m);
}
void solve() 
{
	cin>>n>>m>>a>>b;
	vector<ll>vt(n*m,LLONG_MAX),vc(n*m,0);
	priority_queue<pair<ll,ll>,vector<pair<ll,ll>>,greater<pair<ll,ll>>>pq;
	for(ll i=0;i<a;i++)
	{
		ll x,y;
		cin>>x>>y;
		vt[sum(x-1,y-1)]=0;
		pq.push({0,sum(x-1,y-1)});
	}
	for(ll i=0;i<b;i++)
	{
		ll x,y,z;
		cin>>x>>y>>z;
		vc[sum(x-1,y-1)]=z;
	}
	while(!pq.empty())
	{
		auto [u,v]=pq.top();
		ll x=v/m,y=v%m;
		pq.pop();
		for(ll i=0;i<4;i++)
		{
			ll x1=x+dx[i],y1=y+dy[i],f=sum(x1,y1);
			if(check(x1,y1)&&vt[f]==LLONG_MAX)
			{
				ans=max(max(vc[f],u+1),ans);
//                 cout<<x<<" "<<y<<" "<<max(vc[f],u+1)<<endl;
				pq.push({max(vc[f],u+1),f});
				vt[f]=0;
			}
		}
	}
	cout<<ans<<endl;
}
int main()
{
	ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
	ll _=1;
// 	cin>>_;
	while(_--)
		solve();
	return 0;
}

如有错误烦请指正谢谢