#include <bits/stdc++.h>
using namespace std;
int d2x[] = {1, -1, 0, 0, 1, -1, 1, -1};
int d2y[] = {0, 0, 1, -1, 1, -1, -1, 1};
int d3x[] = {1, -1, 0, 0, 0, 0};
int d3y[] = {0, 0, 1, -1, 0, 0};
int d3z[] = {0, 0, 0, 0, 1, -1};
struct edge {
  long long from, to, w;
  bool train;
  bool used;
  edge(long long from, long long to, long long w, bool train)
      : from(from), to(to), w(w), train(train) {}
  bool operator<(const edge& e) const { return w > e.w; }
};
const double EPS = (1e-9);
const long long OO = 1e10;
int n, m, k;
int cnt = 0;
vector<vector<edge> > adj;
vector<long long> dist;
bool visited[100005];
void disjkstra(int src);
int main() {
  scanf("%d%d%d", &n, &m, &k);
  memset(visited, true, sizeof(visited));
  adj = vector<vector<edge> >(n + 1);
  dist = vector<long long>(n + 1, OO);
  long long from, to, cost;
  for (int i = 0; i < m; i++) {
    scanf("%lld%lld%lld", &from, &to, &cost);
    adj[from].push_back(edge(from, to, cost, false));
    adj[to].push_back(edge(to, from, cost, false));
  }
  for (int i = 0; i < k; i++) {
    scanf("%lld%lld", &to, &cost);
    adj[1].push_back(edge(1, to, cost, true));
  }
  disjkstra(1);
  for (int i = 2; i <= n; ++i)
    if (visited[i]) ++cnt;
  cout << k - cnt << endl;
  return 0;
}
void disjkstra(int src) {
  dist[src] = 0;
  priority_queue<edge> q;
  q.push(edge(-1, src, 0, false));
  while (!q.empty()) {
    edge e = q.top();
    q.pop();
    if (e.w > dist[e.to]) {
      continue;
    }
    for (int i = 0; i < ((int)((adj[e.to]).size())); i++) {
      edge ne = adj[e.to][i];
      if (dist[ne.to] > dist[ne.from] + ne.w) {
        visited[ne.to] = ne.train;
        ne.w = dist[ne.to] = dist[ne.from] + ne.w;
        q.push(ne);
      } else if (dist[ne.to] == dist[ne.from] + ne.w) {
        visited[ne.to] = visited[ne.to] && ne.train;
      }
    }
  }
}
