题意:
题意就是一个人要从a->b->c,然后让你分配每条路的权值,让这条路径的花费最少。
思考:
刚开始可能会想,这不就是a到b的最短路和b到c的最短路是多少吗,但是在更新最短路的时候中间可能走到别的地方的点,所以有可能是a->x->b->x->c,这样就是枚举一个点x,然后求出来a到x和b到x和c到x,再加上b到x。
代码:
int T,n,m;
int a,b,c;
int va[N];
int sum[N];
int da[N],db[N],dc[N];
vector<int > e[N];
void bfs(int A,int dist[])
{
for(int i=1;i<=n;i++) dist[i] = inf;
queue<int > q;
q.push(A);
dist[A] = 0;
while(q.size())
{
auto now = q.front();
q.pop();
for(auto spot:e[now])
{
if(dist[spot]>dist[now]+1)
{
dist[spot] = dist[now]+1;
q.push(spot);
}
}
}
}
signed main()
{
IOS;
cin>>T;
while(T--)
{
cin>>n>>m>>a>>b>>c;
for(int i=1;i<=n;i++) e[i].clear();
for(int i=1;i<=m;i++) cin>>va[i];
sort(va+1,va+1+m); //先排序一下
for(int i=1;i<=m;i++) sum[i] = sum[i-1]+va[i]; //要走那么长的路就是这个前缀和
for(int i=1;i<=m;i++)
{
int u,v;
cin>>u>>v;
e[u].pb(v);
e[v].pb(u);
}
bfs(a,da);bfs(b,db);bfs(c,dc);
int minn = inf;
for(int i=1;i<=n;i++)
{
if(da[i]+db[i]+dc[i]<=m) //这里要满足<=m,如果超过的话,这就不对.
minn = min(minn,sum[db[i]]+sum[da[i]+db[i]+dc[i]]);
}
cout<<minn<<"\n";
}
return 0;
}
总结:
要总结到点之间要如何转移之类的。