E. Weights Distributing(图论)

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

题意:

给出一个无向图,m条边,有m个值,要求一一对应。现在从a到b再到c的路程最短。

解析:

显然找到一个点d,bd算两次,ad和cd算一次。

代码:

/*
 *  Author : Jk_Chen
 *    Date : 2020-04-21-23.15.41
 */
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define rep(i,a,b) for(int i=(int)(a);i<=(int)(b);i++)
#define per(i,a,b) for(int i=(int)(a);i>=(int)(b);i--)
#define mmm(a,b) memset(a,b,sizeof(a))
#define pb push_back
#define pill pair<int, int>
#define fi first
#define se second
void test(){cerr<<"\n";}
template<typename T,typename... Args>void test(T x,Args... args){cerr<<x<<" ";test(args...);}
const LL mod=1e9+7;
const int maxn=2e5+9;
const int inf=0x3f3f3f3f;
LL rd(){ LL ans=0; char last=' ',ch=getchar();
    while(!(ch>='0' && ch<='9'))last=ch,ch=getchar();
    while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();
    if(last=='-')ans=-ans; return ans;
}
#define rd rd()
/*_________________________________________________________begin*/

#define rep_e(i,p,u) for(int i=head[p],u=to[i];i;i=nex[i],u=to[i])
int head[maxn],to[maxn<<1],nex[maxn<<1],now;
void add(int a,int b){
    nex[++now]=head[a];head[a]=now;to[now]=b;
}
void init_edge(){
    memset(head,0,sizeof head);
    now=0;
}
/*_________________________________________________________edge*/

int n,m;
int dis[3][maxn];
int BFS(int p,int dis[]){
    rep(i,1,n)dis[i]=inf;
    dis[p]=0;
    queue<int>Q;
    Q.push(p);
    while(!Q.empty()){
        p=Q.front();Q.pop();
        rep_e(i,p,u){
            if(dis[u]>dis[p]+1){
                dis[u]=dis[p]+1;
                Q.push(u);
            }
        }
    }
}
LL len[maxn];

int main(){
    int t=rd;
    while(t--){
        n=rd,m=rd;
        rep(i,1,n)head[i]=0;
        now=0;
        
        int a=rd,b=rd,c=rd;
        rep(i,1,m)len[i]=rd;
        sort(len+1,len+1+m);
        rep(i,1,m){
            int aa=rd,bb=rd;
            add(aa,bb);
            add(bb,aa);
        }
        rep(i,1,m)len[i]+=len[i-1];
        BFS(a,dis[0]);
        BFS(b,dis[1]);
        BFS(c,dis[2]);
        LL ans=2e18;
        rep(i,1,n){
            LL l1=dis[1][i];
            LL l2=dis[0][i];
            LL l3=dis[2][i];
            l2+=l3;
            if(l1+l2>m)continue;
            ans=min(ans,len[l1]*2ll+(len[l1+l2]-len[l1]));
        }
        printf("%lld\n",ans);
    }
    return 0;
}

/*_________________________________________________________end*/

发布了790 篇原创文章 · 获赞 348 · 访问量 22万+

猜你喜欢

转载自blog.csdn.net/jk_chen_acmer/article/details/105691941