分析:
依次将每个牧场作为源点s,使用spfa,计算源点到其他牧场的最短路,函数内计算所有牧场奶牛到源点s的距离和,更新最小值。
错误:
题目要求c<1450,无向图为两条边,边数应小于2900。
一开始e[3000]处错误设置为e[2000],数据大时会超时。
#include<stdio.h>
#include<string.h>
#define min(a,b) (((a)<(b))?(a):(b))
#define inf 0x3f3f3f3f
#define M 1000;
int n,p1,c; //牧场数p1
int cnt[1000]; //i号牧场的奶牛数
int d[1000];
int ans=inf;
struct edge{
int v,next,w;
}e[3000]; //无向图,两条边
int eid,p[1000],vst[1000],q[1000],r,l;
void insert(int x,int y,int w) {
e[eid].v=y;
e[eid].next=p[x];
e[eid].w=w;
p[x]=eid++;
}
void insert2(int x,int y,int w) {
insert(x,y,w);
insert(y,x,w);
}
void spfa(int s){
memset(vst,0,sizeof(vst));
memset(d,inf,sizeof(d));
r=0,l=0;
d[s]=0;
vst[s]=1;
q[r++]=s;
r%=M;
while(l!=r) {
int now=q[l++];
l%=M;
vst[now]=0;
for(int j=p[now];~j;j=e[j].next) {
int v=e[j].v;
if(d[v]>d[now]+e[j].w){
d[v]=d[now]+e[j].w;
if(!vst[v]){
q[r++]=v;
r%=M;
vst[v]=1;
}
}
}
}
int sum=0;
for(int i=1;i<=p1;i++) {
sum+=cnt[i]*d[i];
}
ans=min(ans,sum);
}
int main() {
freopen("butter.in","r",stdin);
freopen("butter.out","w",stdout);
scanf("%d%d%d",&n,&p1,&c);
for(int i=1;i<=n;i++) {
int x;
scanf("%d",&x);
cnt[x]++;
}
memset(p,-1,sizeof(p));
for(int i=1;i<=c;i++) {
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
insert2(u,v,w);
}
for(int i=1;i<=p1;i++) {
spfa(i);
}
printf("%d",ans);
return 0;
}