题意:给你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; }