답안 #129697

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
129697 2019-07-13T04:59:01 Z 임유진(#3141) 물병 (JOI14_bottle) C++14
0 / 100
478 ms 53852 KB
#include <stdio.h>
#include <queue>
#include <algorithm>

using namespace std;

#define MAXH 2005
#define MAXP 200005
#define fi first
#define se second

typedef pair<int, int> pii;

struct edge {
	int A, B, D;
} ed[8000005];

const int mm[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
char m[MAXH][MAXH];
pii bui[MAXP], que[MAXP];
queue<pii> q;
int dis[MAXH][MAXH], fro[MAXH][MAXH];
int en;
int uni[MAXP];
vector<pii> mst[MAXP];
pii par[20][MAXP];
int dep[MAXP];
bool chk[MAXP];

int guni(int x) { return x == uni[x] ? x : uni[x] = guni(uni[x]); }

void unite(int x, int y) { uni[guni(x)] = guni(y); }

void dfs(int x) {
	//printf("dfs(%d)\n", x);
	chk[x] = true;
	for(auto a : mst[x]) if(!chk[a.se]) {
		par[0][a.se] = make_pair(a.fi, x);
		dep[a.se] = dep[x] + 1;
		dfs(a.se);
	}
}

int lcad(int x, int y) {
	int ans = 0;
	if(dep[x] < dep[y]) swap(x, y);
	for(int i = 0; i < 20; i++) if((dep[x] - dep[y]) & (1 << i)) {
		ans = max(ans, par[i][x].fi);
		x = par[i][x].se;
	}
	if(x == y) return ans;
	for(int i = 19; i >= 0; i--) if(par[i][x].se != par[i][y].se) {
		ans = max(ans, max(par[i][x].fi, par[i][y].fi));
		x = par[i][x].se;
		y = par[i][y].se;
	}
	return max(ans, max(par[0][x].fi, par[0][y].fi));
}

int main() {
	int H, W, P, Q;

	//freopen("input.txt", "r", stdin);

	scanf("%d%d%d%d", &H, &W, &P, &Q);
	for(int i = 1; i <= H; i++) scanf("%s", m[i] + 1);
	for(int i = 1; i <= P; i++) scanf("%d%d", &bui[i].fi, &bui[i].se);
	for(int i = 0; i < Q; i++) scanf("%d%d", &que[i].fi, &que[i].se);

	for(int i = 1; i <= H; i++) m[i][0] = m[i][W + 1] = '#';
	for(int i = 1; i <= W; i++) m[0][i] = m[H + 1][i] = '#';

	for(int i = 1; i <= P; i++) {
		fro[bui[i].fi][bui[i].se] = i;
		q.push(bui[i]);
	}
	while(!q.empty()) {
		pii t = q.front();
		q.pop();
		for(int i = 0; i < 4; i++) {
			int a = t.fi + mm[i][0], b = t.se + mm[i][1];
			if(fro[a][b] == 0 && m[a][b] == '.') {
				fro[a][b] = fro[t.fi][t.se];
				dis[a][b] = dis[t.fi][t.se] + 1;
				q.push(make_pair(a, b));
			}
		}
	}
/*
	for(int i = 1; i <= H; i++) {
		for(int j = 1; j <= W; j++) printf("(%d, %d)", dis[i][j], fro[i][j]);
		printf("\n");
	}
	*/

	for(int i = 1; i <= H; i++) for(int j = 1; j < W; j++) 
		if(fro[i][j + 1] != 0 && fro[i][j] != fro[i][j + 1])
			ed[en++] = (edge) { fro[i][j], fro[i][j + 1], dis[i][j] + dis[i][j + 1] };
	for(int i = 1; i < H; i++) for(int j = 1; j <= W; j++) 
		if(fro[i][j] != 0 && fro[i + 1][j] != 0 && fro[i][j] != fro[i + 1][j])
			ed[en++] = (edge) { fro[i][j], fro[i + 1][j], dis[i][j] + dis[i + 1][j] };

	//for(int i = 0; i < en; i++) printf("[%d %d %d]\n", ed[i].A, ed[i].B, ed[i].D);

	sort(ed, ed + en, [&](edge a, edge b) { return a.D < b.D; } );
	for(int i = 1; i <= P; i++) uni[i] = i;
	for(int i = 0; i < en; i++) if(guni(ed[i].A) != guni(ed[i].B)) {
		unite(ed[i].A, ed[i].B);
		mst[ed[i].A].push_back(make_pair(ed[i].D, ed[i].B));
		mst[ed[i].B].push_back(make_pair(ed[i].D, ed[i].A));
	}

	/*
	for(int i = 1; i <= P; i++) {
		for(auto a : mst[i]) printf("(%d, %d)", a.fi, a.se);
		printf("\n");
	}
	*/

	for(int i = 1; i <= P; i++) if(!chk[i]) {
		par[0][i].se = i;
		dfs(i);
	}
	/*
	for(int i = 1; i <= P; i++) printf("(%d, %d)", par[0][i].fi, par[0][i].se);
	printf("\n");
	*/
	for(int i = 1; i < 20; i++) for(int j = 1; j <= P; j++)
		par[i][j] = make_pair(max(par[i - 1][j].fi, par[i - 1][par[i - 1][j].se].fi), par[i - 1][par[i - 1][j].se].se);
	//printf("*\n");

	for(int i = 0; i < Q; i++) printf("%d\n", guni(que[i].fi) == guni(que[i].se) ? lcad(que[i].fi, que[i].se) : -1);
	return 0;
}

Compilation message

bottle.cpp: In function 'int main()':
bottle.cpp:65:7: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  scanf("%d%d%d%d", &H, &W, &P, &Q);
  ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~
bottle.cpp:66:35: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  for(int i = 1; i <= H; i++) scanf("%s", m[i] + 1);
                              ~~~~~^~~~~~~~~~~~~~~~
bottle.cpp:67:35: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  for(int i = 1; i <= P; i++) scanf("%d%d", &bui[i].fi, &bui[i].se);
                              ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
bottle.cpp:68:34: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
  for(int i = 0; i < Q; i++) scanf("%d%d", &que[i].fi, &que[i].se);
                             ~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# 결과 실행 시간 메모리 Grader output
1 Incorrect 9 ms 6008 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 44 ms 27512 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 44 ms 27516 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 478 ms 53852 KB Output isn't correct
2 Halted 0 ms 0 KB -