[USACO3.2]Sweet Butter

题目大意:
给定一张$k$个结点,$m$条边的无向图,其中有$n$个点被标记,在这$k$个点中找出一个点使得这个点到那$n$个点的最短距离之和最小,求出这个距离和。

思路:
对于每个标记结点跑最短路,最后枚举每个结点,求出其到各个标记结点的最短距离和,取$min$。

 1 #include<cstdio>
 2 #include<cctype>
 3 #include<functional>
 4 #include<ext/pb_ds/priority_queue.hpp>
 5 inline int getint() {
 6     char ch;
 7     while(!isdigit(ch=getchar()));
 8     int x=ch^'0';
 9     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
10     return x;
11 }
12 const int inf=0x7fffffff;
13 const int V=801;
14 struct Edge {
15     int to,w;
16 };
17 std::vector<Edge> e[V];
18 inline void add_edge(const int u,const int v,const int w) {
19     e[u].push_back((Edge){v,w});
20 }
21 struct Vertex {
22     int id,dis;
23     bool operator > (const Vertex &another) const {
24         return dis>another.dis;
25     }
26 };
27 int k;
28 int dis[V][V];
29 __gnu_pbds::priority_queue<Vertex,std::greater<Vertex> > q;
30 __gnu_pbds::priority_queue<Vertex,std::greater<Vertex> >::point_iterator p[V];
31 inline void Dijkstra(const int s,int *dis) {
32     q.clear();
33     for(int i=1;i<=k;i++) {
34         p[i]=q.push((Vertex){i,dis[i]=(i==s)?0:inf});
35     }
36     while(q.top().dis!=inf) {
37         int x=q.top().id;
38         for(unsigned i=0;i<e[x].size();i++) {
39             Edge &y=e[x][i];
40             if(dis[x]+y.w<dis[y.to]) {
41                 q.modify(p[y.to],(Vertex){y.to,dis[y.to]=dis[x]+y.w});
42             }
43         }
44         q.modify(p[x],(Vertex){x,inf});
45     }
46 }
47 int main() {
48     int n=getint();
49     k=getint();
50     int c=getint();
51     int cow[n];
52     for(int i=0;i<n;i++) cow[i]=getint();
53     while(c--) {
54         int u=getint(),v=getint(),w=getint();
55         add_edge(u,v,w);
56         add_edge(v,u,w);
57     }
58     for(int i=0;i<n;i++) {
59         Dijkstra(cow[i],dis[i]);
60     }
61     int ans=inf;
62     for(int i=1;i<=k;i++) {
63         int tmp=0;
64         for(int j=0;j<n;j++) {
65             tmp+=dis[j][i];
66         }
67         ans=std::min(ans,tmp);
68     }
69     printf("%d\n",ans);
70     return 0;
71 }

 

posted @ 2017-08-19 08:44  skylee03  阅读(159)  评论(0编辑  收藏  举报