新年好
思路:Dijkstra与dfs结合,先求出佳佳和他的五个亲戚分别到别的点的最短路径,然后打表,dfs求全排列直接查表即可
具体代码如下
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
#define x first
#define y second
using namespace std;
typedef pair<int, int> PII;
const int N = 50010, M = 200010, INF = 0x3f3f3f3f;
int n, m;
int h[N], e[M], w[M], ne[M], idx;
int dis[6][N];
int source[6];
bool st[N];
void add(int a, int b, int c){
e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx++;
}
void dijkstra(int s, int dis[]){
memset(dis, 0x3f, N*4);
memset(st, 0, sizeof st);
dis[s] = 0;
priority_queue<PII, vector<PII>, greater<PII> > heap;
heap.push({0, s});
while(heap.size()){
PII t = heap.top();
heap.pop();
int ver = t.y, distance = t.x;
if(st[ver]) continue;
st[ver] = true;
for(int i=h[ver]; i!=-1; i=ne[i]){
int j = e[i];
if(dis[j] > distance + w[i]){
dis[j] = distance + w[i];
heap.push({dis[j], j});
}
}
}
}
int dfs(int u, int start, int distance){
if(u > 5) return distance;
int res = INF;
for(int i=1; i<=5; ++i)
if(!st[i]){
int nex = source[i];
st[i] = true;
res = min(res, dfs(u+1, i, distance + dis[start][nex]));
st[i] = false;
}
return res;
}
int main(){
memset(h, -1, sizeof h);
scanf("%d%d", &n, &m);
source[0] = 1;
for(int i=1; i<=5; ++i) scanf("%d", &source[i]);
while(m--){
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
add(a, b, c); add(b, a, c);
}
for(int i=0; i<6; ++i) dijkstra(source[i], dis[i]);
memset(st, 0, sizeof st);
printf("%d\n", dfs(1, 0, 0));
return 0;
}