首页 > 其他 > 详细

[CF1343E] Weights Distributing - 贪心,BFS

时间:2020-09-01 11:00:27      阅读:44      评论:0      收藏:0      [点我收藏+]

Description

给定无向图和一个权值多重集,用它给无向图分配边权,要求是全排列,求路径 \(a \to b \to c\) 最短长度。

Solution

考虑到 \(a \to b\)\(b \to c\) 可能有一段重复的 \(b - d\),枚举 \(d\),这样只需求出 \(a \to d, d \to b, b \to d, d \to c\) 的最小值

设对某个 \(d\)\(a-d,b-d,c-d\) 长度分别为 \(x,y,z\),则我们会将最小的 \(y\) 个边权分配给 \(b-d\),剩余中最小的 \(x+z\) 个分配给 \(a-d,c-d\),因此可以在 \(O(1)\) 中计算出长度,故时间复杂度为 \(O(n)\)

#include <bits/stdc++.h>
using namespace std;

#define int long long
const int N = 200005;
const int dbg = 0;

vector <int> g[N];
int p[N],dis[3][N],vis[N],t1,t2,n,m,a,b,c;

void bfs(int v0,int id)
{
    queue <int> que;
    que.push(v0);
    dis[id][v0]=0;
    while(!que.empty())
    {
        int p=que.front();
        que.pop();
        for(int q:g[p])
        {
            if(dis[id][q]>dis[id][p]+1)
            {
                dis[id][q]=dis[id][p]+1;
                que.push(q);
            }
        }
    }
}

void solve()
{
    cin>>n>>m>>a>>b>>c;
    for(int i=1;i<=m;i++)
    {
        cin>>p[i];
    }
    for(int i=1;i<=m;i++)
    {
        cin>>t1>>t2;
        g[t1].push_back(t2);
        g[t2].push_back(t1);
    }
    for(int i=1;i<=n;i++)
    {
        dis[0][i]=dis[1][i]=dis[2][i]=1e9;
    }
    dis[0][a]=dis[1][b]=dis[2][c]=0;
    for(int i=1;i<=n;i++)
    {
        vis[i]=0;
    }
    bfs(a,0);
    for(int i=1;i<=n;i++)
    {
        vis[i]=0;
    }
    bfs(b,1);
    for(int i=1;i<=n;i++)
    {
        vis[i]=0;
    }
    bfs(c,2);
    sort(p+1,p+m+1);
    int ans=1e18;
    int *da=dis[0],*db=dis[1],*dc=dis[2];
    for(int i=1;i<=m;i++)
    {
        p[i]+=p[i-1];
    }
    if(dbg)
    {
        cout<<"sum seq: ";
        for(int i=1;i<=m;i++)
        {
            cout<<p[i]<<" ";
        }
        cout<<endl;
    }
    int *sum=p;
    for(int i=1;i<=n;i++)
    {
        int x=da[i],y=db[i],z=dc[i];
        if(dbg)
        {
            cout<<" i="<<i<<" x,y,z="<<x<<y<<z<<endl;
        }
        if(x+y+z>m) continue;
        int tmp=0;
        tmp+=sum[x+y+z]+sum[y];
        if(dbg)
        {
            cout<<"  "<<sum[x+y+z]<<"+"<<sum[y]<<"="<<tmp<<endl;
        }
        ans=min(ans,tmp);
    }
    cout<<ans<<endl;
    for(int i=1;i<=n;i++)
    {
        g[i].clear();
        p[i]=0;
    }
}

signed main()
{
    int t;
    cin>>t;
    while(t--)
    {
        solve();
    }
}

[CF1343E] Weights Distributing - 贪心,BFS

原文:https://www.cnblogs.com/mollnn/p/13594381.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!