题意:给你n个点,c条无向边,以及p头牛所在的点编号,求所有牛同时走向一个点的总距离和的最小值,直接p次最短路就行。。。
/*
ID: yangdy03
PROG: butter
LANG: C++
*/
#include<iostream>
#include<cstring>
#include<algorithm>
#include<fstream>
#include<cstdio>
#include<queue>
#include<vector>
using namespace std;
ofstream fout ("butter.out");
ifstream fin ("butter.in");
const int maxn = 1000;
const int INF = 1e7;
int N, P, C, ans;
int d[maxn][maxn], a[maxn], p[maxn], dist[maxn][maxn];
bool done[maxn];
struct Heap
{
int d, u;
bool operator < (const Heap & rhs) const
{
return d > rhs.d;
}
};
struct Edge
{
int from, to, dist;
};
vector<Edge> edges;
vector<int> G[maxn];
void init()
{
memset(d, 0, sizeof(d));
for(int i=0; i<=maxn; i++) G[i].clear();
edges.clear();
}
void add(int from, int to, int dist)
{
edges.push_back((Edge){from, to, dist});
edges.push_back((Edge){to, from, dist});
int m = edges.size();
G[from].push_back(m-2);
G[to].push_back(m-1);
}
void dij(int s)
{
priority_queue<Heap> q;
for(int i=1; i<=P; i++) d[s][i] = INF;
d[s][s] = 0;
memset(done, 0, sizeof(done));
q.push((Heap){0, s});
while(!q.empty())
{
Heap x = q.top(); q.pop();
int u = x.u;
if(done[u]) continue;
done[u] = true;
for(int i=0; i<G[u].size(); i++)
{
Edge& e = edges[G[u][i]];
if(d[s][e.to] > d[s][u] + e.dist)
{
d[s][e.to] = d[s][u] + e.dist;
q.push((Heap){d[s][e.to], e.to});
}
}
}
};
void solve()
{
ans = INF;
for(int i=1; i<=P; i++)
{
int tmp = 0;
for(int j=0; j<N; j++)
tmp += d[a[j]][i];
ans = min(ans, tmp);
}
}
int main()
{
int x, y, z;
fin>>N>>P>>C;
init();
for(int i=0; i<N; i++) fin>>a[i];
for(int i=0; i<C; i++)
{
fin>>x>>y>>z;
add(x, y, z);
}
for(int i=0; i<N; i++)
{
dij(a[i]);
}
solve();
fout<<ans<<endl;
}