#include using namespace std; typedef long long ll; // Graph layout // -- Each problem has its own Edge structure. // If you see "typedef int Edge;" at the top of an algorithm, change // vector > nbr; ---> vector > nbr; // Dijkstra's Algorithm [Sparse Graphs] (Directed and Undirected) -- O((n+m)*log(n+m)) // -- Edge weight >= 0. May use get_path to obtain the path. struct Edge{ ll to,weight; }; // weight can be double or other numeric type typedef vector::const_iterator EdgeIter; struct Graph { vector > nbr; int num_nodes; Graph(int n) : nbr(n), num_nodes(n) { } void add_edge(int u, int v, ll weight) { Edge e = {v,weight}; nbr[u].push_back(e); } }; void dijkstra(const Graph &G, int src, vector &D) { typedef pair pii; int n = G.num_nodes; vector used(n, false); priority_queue, greater > fringe; D.resize(n); fill(D.begin(), D.end(), -1); D[src] = 0; fringe.push(make_pair(0, src)); while (!fringe.empty()) { pii next = fringe.top(); fringe.pop(); int u = next.second; if (used[u]) continue; used[u] = true; for (EdgeIter it = G.nbr[u].begin(); it != G.nbr[u].end(); ++it) { int v = it->to; ll weight = it->weight + next.first; if (used[v]) continue; if (D[v] == -1 || weight < D[v]) { D[v] = weight; fringe.push(make_pair(D[v], v)); } } } } // Unweighted Bipartite Matching (Undirected Only) -- O(m*sqrt(n)) // -- Your match is stored in "mate". (mate == -1 if there is no match) // -- adj is an adjacency list that indexes the other set // Ex: U[0].adj[0] == x means there is an edge from U[0] to V[x] struct Node{ vector adj; int mate,pred; }; // Ignore "pred" -- For internal use. void add_edge(Node U[],int u_node,Node V[],int v_node){ U[u_node].adj.push_back(v_node); V[v_node].adj.push_back(u_node); } // u is the number of elements in U // v is the number of elements in V int match(Node U[],int u,Node V[],int v){ for(int i=0;i q1,q2; for(int i=0;i= 0;W=(W == U ? V : U)) i = W[i].pred; if(i == -2) continue; numMatches++; for(i = x;i >= 0;){ int p = V[i].pred; V[i].pred = -2; V[i].mate = p; U[p].mate = i; i = U[p].pred; U[p].pred = -2; } } } return numMatches; } int main() { int n, m, c; cin >> n >> m >> c; int client[300]; for (int i = 0; i < c; i++) { cin >> client[i]; } Graph G(n); for (int i = 0; i < m; i++) { int u, v; ll l; cin >> u >> v >> l; G.add_edge(u, v, l); } vector Droot; dijkstra(G, 0, Droot); Node U[301], V[301]; for (int i = 0; i < c; i++) { vector Dc; dijkstra(G, client[i], Dc); for (int j = 0; j < c; j++) { if (i == j) continue; if (Dc[client[j]] >= 0 && Droot[client[i]] + Dc[client[j]] == Droot[client[j]]) { add_edge(U, i, V, j); } } } cout << c - match(U, c, V, c) << endl; return 0; }