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;
    }
  • 相关阅读:
    LeetCode 977 有序数组的平方
    LeetCode 24 两两交换链表中的节点
    LeetCode 416 分割等和子集
    LeetCode 142 环形链表II
    LeetCode 106 从中序与后序遍历序列构造二叉树
    LeetCode 637 二叉树的层平均值
    LeetCode 117 填充每个节点的下一个右侧节点
    LeetCode 75 颜色分类
    redhat 7.4 挂载ntfs格式的u盘并且使用
    redhat 查看CPU frequency scaling(CPU频率缩放)
  • 原文地址:https://www.cnblogs.com/-Ackerman/p/13177446.html
Copyright © 2011-2022 走看看