CF 1433G G. Reducing Delivery Cost 最短路+暴力枚举

原题链接

文章目录

题意

有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   │ . │←─┘│
 * └─────┴────┴────┴───────────────────────┴────┴────┴────┴────┘ └───┴───┴───┘ └───────┴───┴───┘
 */

猜你喜欢

转载自blog.csdn.net/kaka03200/article/details/111411322
今日推荐