【题目描述】
农夫John知道每只奶牛都在各自喜欢的牧场(一个牧场不一定只有一头牛)。给出各头牛在的牧场和牧场间的路线,找出使所有牛到达的路程和最短的牧场(他将把糖放在那)。
【题目链接】
https://www.luogu.org/problemnew/show/P1828
【算法】
算出任意两个牧场间最短距离,枚举目的地,取最小值。floyd会超时,对每个点用spfa。
【代码】
1 #include <bits/stdc++.h> 2 using namespace std; 3 struct edge{ int to,next,val; }e[3010]; 4 int n,p,C,a,b,c,tot,ans=1e9,i,j; 5 int head[810],rec[810],d[810][810],v[810]; 6 void add(int from,int to,int val) 7 { 8 e[++tot].to=to,e[tot].val=val; 9 e[tot].next=head[from],head[from]=tot; 10 } 11 int main() 12 { 13 scanf("%d%d%d",&n,&p,&C); 14 for(i=1;i<=n;i++) scanf("%d",&a),rec[a]++; 15 for(i=1;i<=C;i++) scanf("%d%d%d",&a,&b,&c),add(a,b,c),add(b,a,c); 16 memset(d,0x3f,sizeof(d)); 17 for(i=1;i<=p;i++) { 18 memset(v,0,sizeof(v)); 19 queue<int> q; 20 d[i][i]=0; 21 q.push(i); v[i]=1; 22 while(q.size()) { 23 int x=q.front(); q.pop(); 24 v[x]=0; 25 for(j=head[x];j;j=e[j].next) { 26 int to=e[j].to,val=e[j].val; 27 if(d[i][to]>d[i][x]+val) { 28 d[i][to]=d[i][x]+val; 29 if(!v[to]) q.push(to),v[to]=1; 30 } 31 } 32 } 33 } 34 for(i=1;i<=p;i++) { 35 int tmp=0; 36 for(j=1;j<=p;j++) 37 tmp=tmp+d[i][j]*rec[j]; 38 ans=min(ans,tmp); 39 } 40 printf("%d ",ans); 41 return 0; 42 }