E. Weights Distributing

题目链接:https://codeforces.com/contest/1343/problem/E

想法:

我们可以考虑假设一个重复点D (D可以和 A、B、C重合) ,那么我们的问题就转化为  A->D->B->D->C   (类似于样例一)

然后我们分别跑三次最短路,然后取枚举 D 就行了。 需要注意一下就是如果此时边的个数 > m 的时候肯定是走了重复的路的,是不符合条件的

其余的情况 贪心就好了

#pragma GCC optimize(3, "Ofast", "inline")//O3优化
#pragma GCC optimize(2)//O2优化
#include <algorithm>
#include <string>
#include <cstring>
#include <vector>
#include <map>
#include <stack>
#include <set>
#include <queue>
#include <cmath>
#include <cstdio>
#include <iomanip>
#include <ctime>
#include <bitset>
#include <cmath>
#include <sstream>
#include <iostream>

#define ll long long
#define ls nod<<1
#define rs (nod<<1)+1
#define pii pair<int,int>
#define mp make_pair
#define pb push_back
#define INF 0x3f3f3f3f3f3f3f3f
#define max(a, b) (a>b?a:b)
#define min(a, b) (a<b?a:b)

#define int ll

const double eps = 1e-10;
const int maxn = 4e5 + 10;
const int MOD = 998244353;

int sgn(double a) { return a < -eps ? -1 : a < eps ? 0 : 1; }

using namespace std;

int w[maxn];
int head[maxn];
int vis[maxn];
int dis_a[maxn],dis_b[maxn],dis_c[maxn];
int cnt = 0;
int sum[maxn];

struct edge{
    int to,nxt,val;
}e[maxn];


void add_edge(int u,int v) {
    e[cnt].to = v;
    e[cnt].val = 1;
    e[cnt].nxt = head[u];
    head[u] = cnt++;
}

void dijstra_a(int s) {
    priority_queue<pii,vector<pii>,greater<pii> > q;
    dis_a[s] = 0;
    q.push({dis_a[s],s});
    while (!q.empty()) {
        int now = q.top().second;
        q.pop();
        if (vis[now])
            continue;
        vis[now] = true;
        for (int i = head[now];~i;i = e[i].nxt) {
            int v = e[i].to;
            if (dis_a[v] > dis_a[now] + e[i].val) {
                dis_a[v] = dis_a[now] + e[i].val;
                q.push({dis_a[v],v});
            }
        }
    }
}

void dijstra_b(int s) {
    priority_queue<pii,vector<pii>,greater<pii> > q;
    dis_b[s] = 0;
    q.push({dis_b[s],s});
    while (!q.empty()) {
        int now = q.top().second;
        q.pop();
        if (vis[now])
            continue;
        vis[now] = true;
        for (int i = head[now];~i;i = e[i].nxt) {
            int v = e[i].to;
            if (dis_b[v] > dis_b[now] + e[i].val) {
                dis_b[v] = dis_b[now] + e[i].val;
                q.push({dis_b[v],v});
            }
        }
    }
}

void dijstra_c(int s) {
    priority_queue<pii,vector<pii>,greater<pii> > q;
    dis_c[s] = 0;
    q.push({dis_c[s],s});
    while (!q.empty()) {
        int now = q.top().second;
        q.pop();
        if (vis[now])
            continue;
        vis[now] = true;
        for (int i = head[now];~i;i = e[i].nxt) {
            int v = e[i].to;
            if (dis_c[v] > dis_c[now] + e[i].val) {
                dis_c[v] = dis_c[now] + e[i].val;
                q.push({dis_c[v],v});
            }
        }
    }
}

signed main() {
    ios::sync_with_stdio(false);
    int t;
    cin >> t;
    while (t--) {
        cnt = 0;
        memset(head,-1,sizeof(head));
        int n,m,a,b,c;
        cin >> n >> m >> a >> b >> c;
        for (int i = 1;i <= m;i++) {
            cin >> w[i];
        }
        sort(w+1,w+1+m);
        for (int i = 1;i <= m;i++) {
            sum[i] = sum[i-1] + w[i];
        }
        for (int i = 1;i <= m;i++) {
            int u,v;
            cin >> u >> v;
            add_edge(u,v);
            add_edge(v,u);
        }
        for (int i = 1;i <= n;i++) {
            vis[i] = 0;
            dis_a[i] = dis_b[i] = dis_c[i] = INF;
        }
        dijstra_a(a);
        for (int i = 1;i <= n;i++)
            vis[i] = 0;
        dijstra_b(b);
        for (int i = 1;i <= n;i++)
            vis[i] = 0;
        dijstra_c(c);
        int ans = INF;
        for (int i = 1;i <= n;i++) {
            int disa_i = dis_a[i];
            int disb_i = dis_b[i];
            int disc_i = dis_c[i];
            if (disa_i + disb_i + disc_i > m)
                continue;
            ans = min(ans,sum[disa_i + disb_i + disc_i] + sum[disb_i]);
        }
        cout << ans << endl;
    }
    return 0;
}
原文地址:https://www.cnblogs.com/-Ackerman/p/13177446.html