zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    Auto.js 入门教程
    几乎纯css实现弹出框
    php curl访问https 域名接口一直报错的问题
    金山打字通刷打字速度脚本
    centos 安装 图像识别工具 tesseract-ocr 流程
    js 实现俄罗斯方块(三)
    小程序报错 .wxss 无法找到
    Redis存储数组
    问题记录-databinding/hilt踩坑记录
    问题记录-CoordinatorLayout+WebView使用遇到的问题
  • 原文地址:https://www.cnblogs.com/-Ackerman/p/13177446.html
Copyright © 2011-2022 走看看