1127. 香甜的黄油
换源点来不断进行单源最短路的计算。
#include <stdio.h> #include <stdlib.h> #include <queue> #include <algorithm> #include <cstring> #define R(x) x = read() using namespace std; typedef pair<int, int> PII; const int N = 810, M = 2910, INF = 0x3f3f3f3f; int n, p, m; int h[N], ne[M], e[M], w[M]; int dist[N], vis[N], idx, Belong[510]; inline int read() { int x = 0; char ch = getchar(); while (ch < '0' || ch > '9') ch = getchar(); while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); } return x; } inline void add(int a, int b, int c) { e[++idx] = b; w[idx] = c; ne[idx] = h[a]; h[a] = idx; } int ans = INF; void DJ(int soc) { priority_queue<PII> q; dist[soc] = 0; q.push({0, soc}); while (!q.empty()) { PII tmp = q.top(); q.pop(); int dis = -tmp.first, id = tmp.second; if (vis[id]) continue; vis[id] = 1; for (int i = h[id]; i; i = ne[i]) { int j = e[i]; if (dist[j] > dis + w[i]) { dist[j] = dis + w[i]; q.push({-dist[j], j}); } } } } void check(int soc) { memset(vis, 0, sizeof(vis)); memset(dist, 0x3f, sizeof(dist)); dist[soc] = 0; DJ(soc); int res = 0; for (int i = 1; i <= n; i++) { if(dist[Belong[i]] == INF) return; res += dist[Belong[i]]; } ans = min(ans, res); } int main() { n = read(); p = read(); m = read(); for (int i = 1; i <= n; i++) R(Belong[i]); for (int i = 1; i <= m; i++) { int a, b, c; R(a); R(b); R(c); add(a, b, c); add(b, a, c); } for (int i = 1; i <= p; i++) check(i); printf("%d\n", ans); system("pause"); return 0; }