Problem:
Problem G: 挨拶の多い本屋さん

なつめは大のねこ好きである。なつめはある日、いつも親しくしている野良ねこたちから、ねこたちが開いている不思議な本屋に行こうと誘われた。その本屋ではたくさんのねこの写真が載った本が売られていると聞き、なつめは喜んでついていくことにした。

なつめは知らなかったのだが、ねこたちに連れられていった本屋は全国にチェーン店を持つ有名店であった。その店ではしっかりとした店員用マニュアルが用意されており、どの店舗でも店員の行動が統一されている。以下はそのマニュアルからの抜粋である。

店員からユークリッド距離10以内のドアからお客様が入店された際には、 X 秒間かけて大声で「いらっしゃいませこんにちは」といわなければならない。

ユークリッド距離50以内の他の店員が「いらっしゃいませこんにちは」と言っているのを聞いた店員は、その「いらっしゃいませこんにちは」の発声終了時に「いらっしゃいませこんにちは」と X 秒かけて大声で復唱しなければならない。ただし、この復唱の発声開始時から過去 Y 秒以内に、別の「いらっしゃいませこんにちは」を発声完了していた店員は、復唱してはならない。

X, Y, 客の位置、店員の配置が与えられるので、客が入ってから店が静かになるまで何秒かかるか計算せよ。復唱が鳴り止まない場合は、"You're always welcome!"と出力せよ。

Input

入力の1行目には、店員の数 N、およびマニュアルに書かれている X, Y がそれぞれ1つの空白文字で区切られて与えられる。2行目はなつめが入店する位置であり、それに続く N 行は N 人の店員の位置を表す座標である。それぞれの位置は x, y 座標を1つの空白文字で区切って与えられ、各数値とも0以上1000以下の整数で与えられる。また、1 <= N <= 1000, 1 <= X, Y <= 100を満たす。

Output

復唱が鳴り止む場合は客が入店してから静かになるまでの時間を、鳴り止まない場合は "You're always welcome!" を1行に出力せよ。

Notes on Submission

上記形式で複数のデータセットが与えられます。入力データの 1 行目にデータセットの数が与えられます。各データセットに対する出力を上記形式で順番に出力するプログラムを作成して下さい。

Sample Input

4
3 3 5
0 0
10 0
40 40
40 90
4 5 10
100 100
50 100
50 150
100 50
100 150
4 60 10
100 100
90 100
110 100
100 90
100 110
4 60 10
100 100
80 100
110 100
100 80
100 110

Output for the Sample Input

9
0
60
You're always welcome!

Solution in C (judge verdict: Accepted)

// AOJ 2191: A Book Shop With a Frequent Greetings
// 2017.12.10

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

#define QSIZE 2000000
#define PARENT(i) ((i)>>1)
#define LEFT(i)   ((i)<<1)
#define RIGHT(i)  (((i)<<1)+1)

typedef struct { int t, n; } QUE;
QUE que[QSIZE+2];
int qsize;

void min_heapify(int i)
{
	int l, r, min;
	QUE qt;

	l = LEFT(i), r = RIGHT(i);
	if (l < qsize && que[l].t < que[i].t) min = l; else min = i;
	if (r < qsize && que[r].t < que[min].t) min = r;
	if (min != i) {
		qt = que[i]; que[i] = que[min]; que[min] = qt;
		min_heapify(min);
	}
}

void deq()
{
	que[0] = que[--qsize];
	min_heapify(0);
}

int max;
void enq(int n, int t)
{
	int i, min;
	QUE qt;

	i = qsize++;
	que[i].t = t, que[i].n = n;
	while (i > 0 && que[min = PARENT(i)].t > que[i].t) {
		qt = que[i]; que[i] = que[min]; que[min] = qt;
		i = min;
	}
}

int xp[1001], yp[1001];
int rel[1001][1001];
int len[1001];
int prev[1001];

char buf[30], *p;
int getint()
{
	int n = 0;
	while (*p >= '0') n = (n<<3) + (n<<1) + (*p++ & 0xf);
	p++;
	return n;
}

int main()
{
	int cno, n, X, Y, x0, y0, i, j, t, ans;

	fgets(p=buf, 10, stdin), cno = getint();
	while (cno--) {
		fgets(p=buf, 30, stdin);
		n = getint(), X = getint(), Y = getint();
		fgets(p=buf, 30, stdin);
		x0 = getint(), y0 = getint();
		for (i = 0; i < n; i++) {
			fgets(p=buf, 30, stdin);
			xp[i] = getint(), yp[i] = getint();
		}

		ans = 0, qsize = 0;
		memset(prev, 0x81, sizeof(prev));
		memset(len, 0, sizeof(len));
		for (i = 0; i < n; i++) {
			if (hypot(xp[i]-x0, yp[i]-y0) <= 10) enq(i, 0);
			for (j = i+1; j < n; j++) {
				if (hypot(xp[i]-xp[j], yp[i]-yp[j]) <= 50)
					rel[i][len[i]++] = j, rel[j][len[j]++] = i;
			}
		}

		while (qsize) {
			i = que[0].n, t = que[0].t, deq();
			if (t > n*X) { ans = -1; break; }
			if (prev[i] < t-Y) {
				t += X;
				prev[i] = t;
				if (t > ans) ans = t;
				for (j = 0; j < len[i]; j++) enq(rel[i][j], t);
			}
		}
		if (ans < 0) puts("You're always welcome!");
		else printf("%d\n", ans);
	}
	return 0;
}