Weights Distributing

You are given an undirected unweighted graph consisting of n vertices and m edges (which represents the map of Bertown) and the array of prices p of length m. It is guaranteed that there is a path between each pair of vertices (districts).

Mike has planned a trip from the vertex (district) a to the vertex (district) b and then from the vertex (district) b to the vertex (district) c. He can visit the same district twice or more. But there is one issue: authorities of the city want to set a price for using the road so if someone goes along the road then he should pay the price corresponding to this road (he pays each time he goes along the road). The list of prices that will be used p is ready and they just want to distribute it between all roads in the town in such a way that each price from the array corresponds to exactly one road.

You are a good friend of Mike (and suddenly a mayor of Bertown) and want to help him to make his trip as cheap as possible. So, your task is to distribute prices between roads in such a way that if Mike chooses the optimal path then the price of the trip is the minimum possible. Note that you cannot rearrange prices after the start of the trip.

You have to answer t independent test cases.

Input

The first line of the input contains one integer t ( 1 ≤ t ≤ 1 0 4 ) t (1≤t≤10^4) t(1t104) — the number of test cases. Then t test cases follow.

The first line of the test case contains five integers n,m,a,b and c ( 2 ≤ n ≤ 2 ⋅ 1 0 5 , n − 1 ≤ m ≤ min ⁡ ( n ( n − 1 ) 2 , 2 ⋅ 1 0 5 ) , 1 ≤ a , b , c ≤ n ) (2\leq n\leq 2\cdot 10^{5},n-1\leq m\leq \min \left( \dfrac {n\left( n-1\right) }{2},2\cdot 10^{5}\right),1\leq a,b,c\leq n ) (2n2105,n1mmin(2n(n1),2105),1a,b,cn)— the number of vertices, the number of edges and districts in Mike’s trip.

The second line of the test case contains m integers p 1 , p 2 , . . . , p m ( 1 ≤ p i ≤ 1 0 9 ) p_1,p_2,...,p_m(1\leq p_i\leq 10^9) p1,p2,...,pm(1pi109),where p i p_i pi is the i-th price from the array.

The following m lines of the test case denote edges: edge i is represented by a pair of integers v i , u i ( 1 ≤ v i , u i ≤ , v i ≠ u i ) v_i,u_i(1\leq v_i,u_i\leq,v_i\neq u_i) vi,ui(1vi,ui,vi=ui),which are the indices of vertices connected by the edge. There are no loops or multiple edges in the given graph, i. e. for each pair ( v i , u i ) (v_i,u_i) (vi,ui)there are no other pairs ( v i , u i ) (v_i,u_i) (vi,ui)or ( u i , v i ) (u_i,v_i) (ui,vi)in the array of edges, and for each pair ( v i , u i ) (v_i,u_i) (vi,ui) the condition v i ≠ u i v_i\neq u_i vi=uiis satisfied.It is guaranteed that the given graph is connected.

It is guaranteed that the sum of n (as well as the sum of m) does not exceed 2 ⋅ 1 0 5 , ( ∑ n ≤ 2 ⋅ 1 0 5 , ∑ m ≤ 2 ⋅ 1 0 5 ) 2\cdot 10^5,(\sum n\leq 2\cdot 10^{5},\sum m\leq 2\cdot 10^{5}) 2105,(n2105,m2105).

Output

For each test case, print the answer — the minimum possible price of Mike’s trip if you distribute prices between edges optimally.

Example

input
2
4 3 2 3 4
1 2 3
1 2
1 3
1 4
7 9 1 5 7
2 10 4 8 5 6 7 3 3
1 2
1 3
1 4
3 2
3 5
4 2
5 6
1 7
6 7
output
7
12

Note

One of the possible solution to the first test case of the example:
在这里插入图片描述
One of the possible solution to the second test case of the example:
在这里插入图片描述
题意:给出一个无向连通图,有 m m m条边,给出 m m m个数值,要求为将 m m m个值分配到 m m m条边,使得从 a a a点→ b b b点, b b b点→ c c c点的路径权值和最小.

思路

  1. 容易想到首先令边权为1,然后求 a → b , b → c a→b,b→c ab,bc的最小距离,然后从小到大赋值.
  2. 因为边权都为1,所以直接 b f s bfs bfs a a a找到 b b b,从 b b b找到 c c c,可以求到 a → b a→b ab b → c b→c bc的距离
  3. 但是中间有一个问题就是 a → b a→b ab b → c b→c bc路径可能会相交
  4. 这个时候我们令交点为 x x x,那么此时路径为 a → x , x → b , b → x , x → c a→x,x→b,b→x,x→c ax,xb,bx,xc,路径和与 x x x有关
  5. 所以需要枚举找到使得路径和最小的 x x x,那么需要求 a , b , c a,b,c a,b,c到每一点的距离
  6. 此时可以 b f s bfs bfs三个点到所有点的距离即可~

代码如下:

#include<bits/stdc++.h>
#include<algorithm>
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;
const int mx=2e5+10;
vector<int>s[mx];//记录图
int da[mx],db[mx],dc[mx];//统计三个点到任意点的距离
int t,n,m,a,b,c;
ll w[mx],ans;//边权

void init()//初始化
{
	ans=1e18;
	w[0]=0;
	memset(da,-1,sizeof(da));
	memset(db,-1,sizeof(db));
	memset(dc,-1,sizeof(dc));
	for(int i=1;i<=n;i++)
	s[i].clear();
}

void bfs(int *dis,int k)//bfs求距离
{
	queue<int>q;
	q.push(k);
	dis[k]=0;
	while(!q.empty())
	{
		int u=q.front();
		q.pop();
		for(auto v:s[u])
		{
			if(dis[v]==-1)
			{
				dis[v]=dis[u]+1;
				q.push(v);
			}
		}
	}
}

int main()
{
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d%d%d%d%d",&n,&m,&a,&b,&c);
		init();
		for(int i=1;i<=m;i++)
		scanf("%lld",&w[i]);
	    sort(w+1,w+1+m);
	    for(int i=1;i<=m;i++)//这里先求一个前缀和
	    w[i]+=w[i-1];
		
		for(int i=1;i<=m;i++)
		{
			int u,v;
			scanf("%d%d",&u,&v);
			s[u].push_back(v);
			s[v].push_back(u);
		}
		
		bfs(da,a);
		bfs(db,b);
		bfs(dc,c);
		
		for(int i=1;i<=n;i++)
		{
		    if(da[i]+db[i]+dc[i]>m)//因为a→x,b→x,c→x只有x一个交点
			continue;             //所以x应满足到三点距离和小于等于总边数
			ans=min(ans,w[db[i]]+w[da[i]+db[i]+dc[i]]);
		}
		
		printf("%lld\n",ans);
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值