题意
有n个点和m条边的图,接着有k个询问,每次给定两个点ai和bi,问所有dis[ai][bi]之和。其中你可以指定一条边的代价为0。
分析
由于n的范围是1000,因此我们可以n^2log(m)的复杂度枚举出任意两点之间的距离。接着暴力去枚举边,如果设a,b这条边为0,那么我们考虑询问的两个点之间的距离怎么去计算。如果这条边不影响u,v之间的距离,那么距离还是dis[u][v],如果这条边对u,v之间的距离有影响,那么路径应该是min(dis[u][a] + dis[b][v], dis[u][b] + dis[a][v])。k*m的复杂度也只有1e6,因此没问题。
AC Code
#include <bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define ACM_LOCAL
using namespace std;
typedef long long ll;
typedef long long ll;
typedef pair<int, int> PII;
const int N = 1000 + 10, M = 2e6 + 10, INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
int n, m, vis[N], h[N], cnt, k;
ll dis[N][N];
struct Query {
int u, v, w;
}q[M], p[M];
struct Edge {
int to, next, w;
}e[M];
void add(int u, int v, int w) {
e[cnt].to = v;
e[cnt].w = w;
e[cnt].next = h[u];
h[u] = cnt++;
}
struct node {
ll d;
int now;
bool operator < (const node& rhs) const {
return d > rhs.d;
}
};
void dij(int s) {
priority_queue<node> q;
memset(dis[s], 0x3f, sizeof dis[s]); dis[s][s] = 0;
memset(vis, 0, sizeof vis);
q.push({
dis[s][s], s});
while (q.size()) {
int u = q.top().now;
q.pop();
if (vis[u]) continue;
vis[u] = 1;
for (int i = h[u]; ~i; i = e[i].next) {
int v = e[i].to;
if (dis[s][v] > dis[s][u] + e[i].w) {
dis[s][v] = dis[s][u] + e[i].w;
if (!vis[v]) q.push({
dis[s][v], v});
}
}
}
}
void solve() {
cin >> n >> m >> k;
memset(h, -1, sizeof h);
for (int i = 1; i <= m; i++) cin >> p[i].u >> p[i].v >> p[i].w, add(p[i].u, p[i].v, p[i].w), add(p[i].v, p[i].u, p[i].w);
for (int i = 1; i <= k; i++) cin >> q[i].u >> q[i].v;
for (int i = 1; i <= n; i++) dij(i);
ll ans = INF;
for (int i = 1; i <= m; i++) {
ll tmp = 0; int a = p[i].u, b = p[i].v;
for (int j = 1; j <= k; j++) {
int u = q[j].u, v = q[j].v;
tmp += min(dis[u][v], min(dis[u][a] + dis[b][v], dis[u][b] + dis[a][v]));
}
ans = min(tmp, ans);
}
cout << ans << endl;
}
signed main() {
ios_base::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
#ifdef ACM_LOCAL
freopen("Test/input", "r", stdin);
freopen("Test/output", "w", stdout);
#endif
solve();
return 0;
}
/*
* ┌───┐ ┌───┬───┬───┬───┐ ┌───┬───┬───┬───┐ ┌───┬───┬───┬───┐ ┌───┬───┬───┐
* │Esc│ │ F1│ F2│ F3│ F4│ │ F5│ F6│ F7│ F8│ │ F9│F10│F11│F12│ │P/S│S L│P/B│ ┌┐ ┌┐ ┌┐
* └───┘ └───┴───┴───┴───┘ └───┴───┴───┴───┘ └───┴───┴───┴───┘ └───┴───┴───┘ └┘ └┘ └┘
* ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐ ┌───┬───┬───┐ ┌───┬───┬───┬───┐
* │~ `│! 1│@ 2│# 3│$ 4│% 5│^ 6│& 7│* 8│( 9│) 0│_ -│+ =│ BacSp │ │Ins│Hom│PUp│ │Num│ / │ * │ - │
* ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤ ├───┼───┼───┤ ├───┼───┼───┼───┤
* │ Tab │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │{ [│} ]│ | \ │ │Del│End│PDn│ │ 7 │ 8 │ 9 │ │
* ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┤ └───┴───┴───┘ ├───┼───┼───┤ + │
* │ Caps │ A │ S │ D │ F │ G │ H │ J │ K │ L │: ;│" '│ Enter │ │ 4 │ 5 │ 6 │ │
* ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────────┤ ┌───┐ ├───┼───┼───┼───┤
* │ Shift │ Z │ X │ C │ V │ B │ N │ M │< ,│> .│? /│ Shift │ │ ↑ │ │ 1 │ 2 │ 3 │ │
* ├─────┬──┴─┬─┴──┬┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤ ┌───┼───┼───┐ ├───┴───┼───┤ E││
* │ Ctrl│ Win│ Alt│ Space │ Alt│ Win│Menu│Ctrl│ │ ← │ ↓ │ → │ │ 0 │ . │←─┘│
* └─────┴────┴────┴───────────────────────┴────┴────┴────┴────┘ └───┴───┴───┘ └───────┴───┴───┘
*/