zoukankan      html  css  js  c++  java
  • Codeforces Round #636 (Div. 3)

    题目链接

    http://codeforces.com/contest/1343/problem/E

    tag

    最短路,贪心,思维

    solution

    给定边权集合,给无向图的每条边赋值,使得从a->b->c的最小花费最少
    有两种情况 :

    1. a到b,b到c不经过同一条边两次
    2. a到b,b到c需经过同一条边两次
      两种情况均可以表示成:设x为可达到a,b,c的点,cost可以表示为dis(a,x) + 2 * dis(b,x)+dic(c,x)
      首先置所有的边权为1,bfs算出a,b,c到每个点的最短路,我们至少要走dis(a,x) + dis(b, x) + dis(c,x)条边,另外dis(b,x)条边走了两次,所以贪心的分配边权的话这条边应该分配给最小的dis(b,x)个边权给这条路径,我们可以将边权排序,做一个前缀和,cost=presum[dis(a,x) + dis(b, x) + dis(c,x)] + pre[dis(b, x)],需要保证dis(a,x) + dis(b, x) + dis(c,x) <= m,因为最多只有m条边

    code

    //created by pyoxiao on 2020/07/08
    #include<bits/stdc++.h>
    #define LL long long
    #define fi first
    #define se second
    #define mp make_pair
    #define pb push_back
    #define CL(a, b) memset(a, b, sizeof(a))
    using namespace std;
    const int mod = 1e9 + 7;
    LL fpow(LL a, LL b, LL p = mod){LL ans = 1; a %= p; while(b) {if(b & 1) ans = ans * a % p; b >>= 1; a = a * a % p;} return ans;}
    LL gcd(LL a, LL b){return b == 0 ? a : gcd(b, a % b);}
    const int N = 2e5 + 7;
    int n, m, a, b, c;
    bool v[N];
    LL da[N], db[N], dc[N], p[N], pre[N];
    vector<int> ver[N];
    queue<int> q;
    void solve() {
        scanf("%d %d %d %d %d", &n, &m, &a, &b, &c);
        for(int i = 0; i <= n; i ++) da[i] = db[i] = dc[i] = 1e18, ver[i].clear();
        for(int i = 1; i <= m; i ++) scanf("%lld", &p[i]);
        sort(p + 1, p + m + 1); pre[0] = 0;
        for(int i = 1; i <= m; i ++) pre[i] = pre[i - 1] + p[i];
        for(int i = 1; i <= m; i ++) {
            int u, v;
            scanf("%d %d", &u, &v);
            ver[u].pb(v);
            ver[v].pb(u);
        }
        while(q.size()) q.pop();
        q.push(a); 
        da[a] = 0;
        while(q.size()) {
            int x = q.front(); q.pop();
            for(auto to : ver[x]) {
                if(da[to] == 1e18) {
                    da[to] = da[x] + 1;
                    q.push(to); 
                }
            }
        }
        while(q.size()) q.pop();
        q.push(b); 
        db[b] = 0;
        while(q.size()) {
            int x = q.front(); q.pop();
            for(auto to : ver[x]) {
                if(db[to] == 1e18) {
                    db[to] = db[x] + 1;
                    q.push(to); 
                }
            }
        }
        while(q.size()) q.pop();
        q.push(c); 
        dc[c] = 0;
        while(q.size()) {
            int x = q.front(); q.pop();
            for(auto to : ver[x]) {
                if(dc[to] == 1e18) {
                    dc[to] = dc[x] + 1;
                    q.push(to); 
                }
            }
        }
        LL ans = LONG_LONG_MAX;
        for(int i = 1; i <= n; i ++) {
            if(da[i] + db[i] + dc[i] <= m) {
                //LL cur = ans;
                ans = min(ans, pre[da[i] + db[i] + dc[i]] + pre[db[i]]);
    
                //cout << i << ' ' << ans << '
    ';
            }
        }
        printf("%lld
    ", ans);
    }
    int main() {
        int T = 1;
        scanf("%d", &T);
        while(T --) 
            solve();
        return 0;
    }
    
  • 相关阅读:
    .Net开源Excel、Word操作组件-NPOI、EPPlus、DocX[转]
    遥感数据下载地址
    在c#中把字符串转为变量名并获取变量值的小例子(转)
    【转】 C# 小技巧之获取变量名称
    arcgis desktop按ctrl键后地图乱移的解决办法
    怎么提高ArcSDE 写入地理数据库的效率
    HowTo Perform the spatial selection 'Share a line segment with' using ArcObjects
    [翻译]Shape comparison language
    Shape comparison language
    [翻译]Shape comparison language[转]
  • 原文地址:https://www.cnblogs.com/pyoxiao/p/13270100.html
Copyright © 2011-2022 走看看