某个村庄i可以打一口井取水花费费用Wi,也可以与有水的村庄连接取水
又因为不可能没有一个村庄不打井(即至少有一个村庄打井,其余村庄连向它)
实际上就可以理解为,将水井看作第N+1个村庄,需要有村庄与这个N+1村庄相连,才能保证所有村庄有水
而村庄i连接到村庄N+1的费用,就可以直接理解为打井的费用Wi
其余部分使用Kruskal最小生成树即可
1 /* 2 Written By StelaYuri 3 */ 4 #include<cstdio> 5 #include<algorithm> 6 using namespace std; 7 struct tube{ 8 int from,to,cost; 9 bool operator < (const tube &a) const{ 10 return cost<a.cost; 11 } 12 }p[90001]; 13 int gp[301]; 14 int find(int a){ 15 return a==gp[a]?a:(gp[a]=find(gp[a])); 16 } 17 int main(){ 18 int i,j,N,d,cnt=0,k=0,sum; 19 scanf("%d",&N); 20 for(i=1;i<=N;i++){ 21 scanf("%d",&d); 22 p[cnt].from=i; 23 p[cnt].to=N+1; 24 p[cnt++].cost=d; 25 gp[i]=i; 26 } 27 for(i=1;i<=N;i++) 28 for(j=1;j<=N;j++){ 29 scanf("%d",&d); 30 if(i==j) 31 continue; 32 p[cnt].from=i; 33 p[cnt].to=j; 34 p[cnt++].cost=d; 35 } 36 sort(p,p+cnt); 37 for(sum=i=0;i<cnt;i++){ 38 if(k==N) 39 break; 40 if(find(p[i].from)!=find(p[i].to)){ 41 gp[find(p[i].to)]=find(p[i].from); 42 sum+=p[i].cost; 43 k++; 44 } 45 } 46 printf("%d\n",sum); 47 48 return 0; 49 }
原文地址:https://www.cnblogs.com/stelayuri/p/12233534.html
时间: 2024-10-11 18:42:37