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++11 (judge verdict: Time Limit Exceeded)

#include <bits/stdc++.h>

using namespace std;

#define rep(i, n) for(int i = 0; i < n; i++)

const int INF = 1 << 29;

int N, R;
int A[3000], B[3000], D[3000];
int cost[1500][1500];
bool used[1500], v[1500];
vector< int > g[1500];

void dfs(int idx, int *dist)
{
  if(v[idx]++) return;
  used[idx]++;
  for(auto &i : g[idx]) {
    if(A[i] == idx && dist[B[i]] + D[i] == dist[idx]) dfs(B[i], dist);
    if(B[i] == idx && dist[A[i]] + D[i] == dist[idx]) dfs(A[i], dist);
  }
}

int main()
{
  fill_n(*cost, 1500 * 1500, INF);
  rep(i, 1500) cost[i][i] = 0;

  cin >> N >> R;
  rep(i, R) {
    cin >> A[i] >> B[i] >> D[i];
    --A[i], --B[i];
    cost[A[i]][B[i]] = cost[B[i]][A[i]] = D[i];
    g[A[i]].push_back(i);
    g[B[i]].push_back(i);
  }
  rep(i, N) rep(j, N) rep(k, N) cost[j][k] = min(cost[j][k], cost[j][i] + cost[i][k]);

  int ret = 0;
  rep(i, N) rep(j, N) if(cost[i][j] != INF) ret = max(ret, cost[i][j]);

  rep(i, N) rep(j, N) {
      memset(v, false, sizeof(v));
      if(cost[i][j] == ret) dfs(j, cost[i]);
    }
  cout << count(used, used + N, false) << endl;
  rep(i, N) if(!used[i]) cout << i + 1 << endl;

}