zoukankan      html  css  js  c++  java
  • codeforces-1343E(贪心+BFS)

    Weights Distributing

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

    题目描述:

    给定n个点m条无向边,再给你a,b,c三个点和m个值,现在要求你将这m个值分配这m条边,使a->b->c的路径的权值最小

    思路:

    分类讨论,一种情况是a->b和b->c这两条路上无交点,这样直接将权值排序后取最小即可,第二种就是两条路上有交点,这时候我们一定可以找到一个交点x,该交点把路径分为a->x,x->b,b->x,x->c这四段路线,因为b->x和x->b本质上是同一条路,所以我们需要优先把较小的权值分配给这条路,可以先用bfs求出a、b、c三个点到所有点的单位距离,接着贪心赋值即可。

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    using ll = long long;
    const int INF = 0x3f3f3f3f;
    const ll N = 1e6;
    const double PI = acos(-1.0);
    #define Test ll tesnum;tesnum = read();while(tesnum--)
    ll read();
    ll val[N];
    vector<int> g[N];
    void bfs(int id,vector<int> &v)
    {
        v[id] = 0;
        queue<int> q;
        q.push(id);
        while(!q.empty()){
            int u = q.front();
            q.pop();
            for(int nx:g[u]){
                if(v[nx]==INF){
                    v[nx] = v[u]+1;
                    q.push(nx);
                }
            }
        }
    }
    int main()
    {
        Test{
            int n,m,a,b,c;
            cin>>n>>m>>a>>b>>c;
            for(int i = 1; i <= m; i++){
                cin>>val[i];
            }
            for(int i = 1; i <= n; i++)g[i].clear();
            sort(val+1,val+1+m);
            for(int i = 1; i <= m; i++){
                int u,v;
                cin>>u>>v;
                g[u].push_back(v);
                g[v].push_back(u);
                val[i] += val[i-1];
            }
            vector<int> disa(n+1,INF);
            vector<int> disb(n+1,INF);
            vector<int> disc(n+1,INF);
            bfs(a,disa);
            bfs(b,disb);
            bfs(c,disc);
            ll ans  = 2e16;
            for(int i = 1; i <= n; i++){
                if(disa[i]+disb[i]+disc[i]>m)continue;
                ans = min(ans,val[disb[i]]+val[disa[i]+disb[i]+disc[i]]);
            }
            cout<<ans<<endl;
        };
        return "BT7274", NULL;
    }
    
    inline ll read() {
        ll hcy = 0, dia = 1;char boluo = getchar();
        while (!isdigit(boluo)) {if (boluo == '-')dia = -1;boluo = getchar();}
        while (isdigit(boluo)) {hcy = hcy * 10 + boluo - '0';boluo = getchar();}
        return hcy * dia;
    }
    
  • 相关阅读:
    Vue 事件修饰符 阻止默认事件
    vue created 生命周期
    续集---网络管理常用命令
    网络管理常用命令(6/14) -netstat命令详解
    系统OOM复位定位
    nohup- Shell后台运行
    一个linux命令(6/13):traceroute命令
    一个linux命令(6/12):cat 命令
    linux命令(6/11)--修改文件的用户组chgrp和文件所有者chown
    Linux终端快捷键
  • 原文地址:https://www.cnblogs.com/cloudplankroader/p/13382709.html
Copyright © 2011-2022 走看看