Problem:
MathJax.Hub.Config({ tex2jax: { inlineMath: [["$","$"], ["\\(","\\)"]], processEscapes: true }});

静かな町

アイヅ国では、毎年、駅伝大会が開催されています。アイヅ国には N 個の町が点在しており、それぞれ 1 から N までの番号が付いています。いくつかの町の間は、互いに直接行き来できる道でつながっています。また、どの町の間もいくつかの道を辿って行き来ができます。大会のコースは、次のようにして決めます。

２つの町のすべての組み合わせについて、最短経路の距離を求める。

それらの中で、最短経路の距離が最大になるような２つの町を、スタートの町とゴールの町とする。町の組み合わせが複数ある場合、そのうちのどれか一つを選ぶ。

選ばれたスタートの町とゴールの町の間の最短経路を大会のコースとする。最短経路が複数ある場合、そのうちのどれか一つを選ぶ。

ヤマト国から来たお坊さんのトクイツは、アイヅ国のできるだけ静かな町に新しいお寺を開きたいと考えています。そのため、駅伝大会のコースに使われる可能性がない町を知りたがっています。

アイヅ国の町を結ぶ道の情報が与えられたとき、駅伝大会のコースに使われる可能性がない町を求めるプログラムを作成せよ。

Input

入力は以下の形式で与えられる。

N R
s1 t1 d1
s2 t2 d2
:
sR tR dR

１行目に町の数 N (2 ≤ N ≤ 1500) と、町の間を直接つなぐ道の数 R (1 ≤ R ≤ 3000) が与えられる。続く R 行に２つの町を双方向に直接つなぐ道が与えられる。si と ti (1 ≤ si < ti ≤ N) は i 番目の道がつなぐ２つの町の番号を表し、di (1 ≤ di ≤ 1000) はその道の長さを表す。ただし、どの２つの町についても、それらを直接つなぐ道は高々１本とする。

Output

与えられた道の情報に対して、駅伝大会のコースになることがない町をすべて出力する。１行目に駅伝大会のコースになることがない町の数 M を出力する。続く M 行に、そのような町の番号を昇順で出力する。

Sample Input 1

4 5
1 2 2
1 3 2
2 3 1
2 4 2
3 4 1

Sample Output 1

1
2

Sample Input 2

7 11
1 2 2
1 3 1
2 4 2
2 5 2
2 6 1
3 4 1
3 5 1
3 6 1
4 7 2
5 7 2
6 7 1

Sample Output 2

3
2
4
5

Solution in C (judge verdict: Runtime Error)

// AOJ 0351 Quiet Town
// 2018.2.25 bal4u

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

#define QMAX 2000
typedef struct { int t, s; } QUE;
QUE que[QMAX]; int qsize;

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

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);
}

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

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

#define INF 0x10101010
#define MAX 1503
int n, dmax;
short hi[MAX], *to[MAX], *dt[MAX];		// to, dist
short hi2[MAX], *to2[MAX];
int   dist[MAX];
char  mk[MAX], ans[MAX];
short q[2*MAX], top, tail;

//#define getchar_unlocked()  getchar()
int in()
{
	int n = 0;
	int c = getchar_unlocked();
	do n = 10*n + (c & 0xf), c = getchar_unlocked();
	while (c >= '0');
	return n;
}

void dijkstra(int start)
{
	int i, s, d, e;
	int max;

	memset(dist, INF, n << 2);
	memset(hi2, 0, n << 1);
	qsize = 0;
	dist[start] = 0, enq(start, 0);
	while (qsize) {
		s = que[0].s, deq();
		for (i = 0; i < hi[s]; i++) {
			e = to[s][i], d = dist[s] + dt[s][i];
			if (dist[e] < d) continue;
			if (dist[e] > d) hi2[e] = 0, dist[e] = d, enq(e, d);
			to2[e][hi2[e]++] = s;
		}
	}

	top = 0, tail = 0;
	max = 0; for (i = 1; i < n; i++) {
		if (dist[i] > max) max = dist[i], q[0] = i, tail = 1;
		else if (dist[i] == max) q[tail++] = i;
	}

	if (max < dmax) return;
	if (max > dmax) { dmax = max, memset(ans, 0, n); }

	memset(mk, 0, n);
	while (top < tail) {
		s = q[top++];
		if (mk[s]) continue;
		mk[s] = 1;
		for (i = 0; i < hi2[s]; i++) {
			e = to2[s][i];
			if (mk[e]) continue;
			q[tail++] = e;
			ans[s] = ans[e] = 1;
		}
	}
}

int main()
{
	int i, j, r, k, s, t, d;
	short *memo;
	
	n = in()+1, r = in();
	memo = malloc(r*6);
	j = 0, i = r; while (i--) {
		memo[j++] = s = in(), hi[s]++;
		memo[j++] = t = in(), hi[t]++;
		memo[j++] = in();
		
	}
	for (s = 0; s < n; s++) if (hi[s]) {
		to [s] = malloc(hi[s] << 1), dt[s] = malloc(hi[s] << 1);
		to2[s] = malloc(hi[s] << 1);
	}
	
	memset(hi, 0, n << 1);
	j = 0; while (r--) {
		s = memo[j++], t = memo[j++], d = memo[j++];
		k = hi[s]++, to[s][k] = t, dt[s][k] = d;
		k = hi[t]++, to[t][k] = s, dt[t][k] = d;
	}
	free(memo);

	k = n-1; if (k > 100) k >>= 1;
	for (s = 1; s <= k; s++) dijkstra(s);

	k = 0; for (s = 1; s < n; s++) if (!ans[s]) k++;
	printf("%d\n", k);
	if (k) for (s = 1; s < n; s++) if (!ans[s]) printf("%d\n", s);
	return 0;
}