Submission #906989

#TimeUsernameProblemLanguageResultExecution timeMemory
906989pan물병 (JOI14_bottle)C++17
100 / 100
2192 ms221452 KiB
#include <bits/stdc++.h>
//#include "bits_stdc++.h"
#define f first
#define s second
#define mp make_pair
#define pb push_back
#define lb lower_bound
#define ub upper_bound
#define show(x) cerr << #x << " is " << x << endl;
#define show2(x,y) cerr << #x << " is " << x << " " << #y << " is " << y << endl;
#define show3(x,y,z) cerr << #x << " is " << x << " " << #y << " is " << y << " " << #z << " is " << z << endl;
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<ld, ll> pd;
typedef pair<string, ll> psl;
typedef pair<ll, ll> pi;
typedef pair<ll, pi> pii;
ll h,w,p, question;
vector<string> m;
ll const MAXN = 200005;
ll const s = 2005;
ll dist[s][s];
bool visited[s][s];
ll par[s][s];
ll twok[MAXN][25];
ll max2k[MAXN][25];
ll depth[MAXN];
ll dx[4] = {0, 1, -1, 0};
ll dy[4] = {1, 0, 0, -1};
vector<pi> adj[MAXN];
vector<pii> edges;
bool compare(pii a, pii b)
{
	return a.f<b.f;
}
vector<ll> link, siz;

ll find(ll a) {
    ll b = a;
    if (link[a] != a) {
        b = find(link[a]);
    }
    link[a] = b;
    return b;
}
bool same(ll a, ll b)
{
	return find(a)==find(b);
}

void unite(ll a, ll b) {
    ll p1 = find(a);
    ll p2 = find(b);
    if (p1 != p2) {
        if (siz[p1] > siz[p2]) {
            swap(p1, p2);
        }
        link[p1] = p2;
        siz[p2] += siz[p1];
    }
}
void dfs(ll p, ll node)
{
	
	for (pi u: adj[node])
	{
		if (p==u.f) continue;
		twok[u.f][0] = node;
		max2k[u.f][0] = u.s;
		depth[u.f] = depth[node]+1;
		dfs(node, u.f);
	}
	
}

void init()
{
	for (ll k=1; k<20; k++)
	{
		for (ll x=0; x<p; ++x)
		{
			if (twok[x][k-1]==-1) continue;
			twok[x][k] = twok[twok[x][k-1]][k-1];
			max2k[x][k] = max(max2k[x][k-1], max2k[twok[x][k-1]][k-1]);
			//show3(x, k, max2k[x][k]);
		}
	}
}


ll lca(ll a, ll b)
{
	ll ans = 0;
	if (depth[a]<depth[b]) swap(a,b);
	ll up = depth[a]-depth[b];
	for (ll i=0; i<20; ++i)
	{
		if (up& (1<<i)) 
		{
			ans = max(ans, max2k[a][i]);
			a=twok[a][i];
		}
	}
	if (a==b) return ans;
	for (ll k=19; k>=0; k--)
	{
		if (twok[a][k]!=twok[b][k])
		{
			ans = max(ans, max2k[a][k]);
			ans = max(ans, max2k[b][k]);
			a=twok[a][k]; b = twok[b][k];
		}
	}
	ans = max(ans, max2k[b][0]);
	ans = max(ans, max2k[a][0]);
	return ans;
	
}

int main()
{
	cin >> h >> w >> p >> question;
	m.resize(h);
	for (ll i=0; i<h; ++i) cin >> m[i];
	queue<pii> q;
	for (ll i=0; i<h; ++i) {for (ll j=0; j<w; ++j){ dist[i][j]=LLONG_MAX;par[i][j] = -1;}}
	link.resize(p);
	siz.assign(p, 1);
	for (ll i=0; i<p; ++i)
	{
		ll x,y;
		cin >> x >> y;
		--x, --y;
		dist[x][y] = 0;
		link[i]=i;
		par[x][y] = i;
		q.push(mp(i, mp(x,y)));
	}
	// use bfs to find shortest edges between building
	while (q.size())
	{
		ll b = q.front().f, x = q.front().s.f, y = q.front().s.s;
		q.pop();
		if (visited[x][y]) continue;
		visited[x][y] = true;
		for (ll k=0; k<4; ++k)
		{
			ll newx = x+dx[k], newy = y+dy[k];
			if (newx<0 || newx>=h || newy<0 || newy>=w || m[newx][newy]=='#') continue;
			if (dist[newx][newy]>dist[x][y]+1)
			{
				dist[newx][newy] = dist[x][y]+1;
				par[newx][newy] = b;
				q.push(mp(b, mp(newx, newy)));
			}
	
		}
		
	}
	
	for (ll x=0; x<h; ++x)
	{
		for (ll y=0; y<w; ++y)
		{
			if (m[x][y]=='#') continue;
			for (ll k=0; k<=1; ++k)
			{
				ll newx = x+dx[k], newy = y+dy[k];
				if (newx<0 || newx>=h || newy<0 || newy>=w || m[newx][newy]=='#') continue;
				if (par[x][y]!=par[newx][newy] && par[x][y]!=-1 && par[newx][newy]!=-1)
				{
					edges.pb(mp(dist[x][y]+dist[newx][newy]+1, mp(par[x][y], par[newx][newy])));
				}
			}
		}
	}
	sort(edges.begin(), edges.end(), compare);
	// Krushkal's MST algorithm
	for (ll i=0; i<edges.size(); ++i)
	{
		
		ll from = edges[i].s.f, to = edges[i].s.s, c = edges[i].f;
		if (same(from ,to)) continue;
		unite(from, to);
		adj[from].pb(mp(to, c));
		adj[to].pb(mp(from, c));
		//show3(from, to, c);
	}
	// 2k decomp
	for (ll k=0; k<20; k++) {for (ll x=0; x<p; ++x) twok[x][k] = -1; }
	for (ll i=0; i<p; ++i) {if (depth[i]==0) {dfs(-1,i);}}
	init();
	//for (ll k=0; k<2; k++) {for (ll x=0; x<p; ++x) {show3(x,k,twok[x][k]);} }
	while (question--)
	{
		ll x,y;
		cin >> x >> y;
		--x, --y;
		if (!same(x, y)) cout << -1 << endl;
		else cout << lca(x, y)-1 << endl;
	}
	
	
	return 0;
}

Compilation message (stderr)

bottle.cpp: In function 'int main()':
bottle.cpp:180:16: warning: comparison of integer expressions of different signedness: 'll' {aka 'long long int'} and 'std::vector<std::pair<long long int, std::pair<long long int, long long int> > >::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  180 |  for (ll i=0; i<edges.size(); ++i)
      |               ~^~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...