zoj1586:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1586
题目大意:最小生成树,不只算两点之间的费用,还要算点的费用,并不是个点只算一次费用,而是每出现一次算一次。
题解:其实只需要在算距离时,把两点的距离加入其中在排序就行了。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 #include<cstring> 3 #include<algorithm> 4 #include<cstdio> 5 #define INF 100000000 6 using namespace std; 7 int n,cas; 8 int g[1002][1002]; 9 int lowcost[1002]; 10 int num[1002]; 11 void prim(int v0){ 12 int sum=0; 13 for(int i=1;i<=n;i++){ 14 lowcost[i]=g[v0][i]; 15 } 16 lowcost[v0]=-1; 17 for(int i=1;i<n;i++){ 18 int min=INF; 19 int v=-1; 20 for(int j=1;j<=n;j++){ 21 if(lowcost[j]!=-1&&lowcost[j]<min){ 22 min=lowcost[j]; 23 v=j; 24 } 25 } 26 if(v!=-1){ 27 sum+=lowcost[v]; 28 lowcost[v]=-1; 29 for(int k=1;k<=n;k++){ 30 if(lowcost[k]!=-1&&g[v][k]<lowcost[k]){ 31 lowcost[k]=g[v][k]; 32 } 33 } 34 } 35 } 36 printf("%d ",sum); 37 } 38 int main(){ 39 scanf("%d",&cas); 40 while(cas--){ 41 scanf("%d",&n); 42 memset(g,0,sizeof(g)); 43 for(int i=1;i<=n;i++) 44 scanf("%d",&num[i]); 45 for(int i=1;i<=n;i++) 46 for(int j=1;j<=n;j++){ 47 scanf("%d",&g[i][j]); 48 g[i][j]+=num[i]+num[j]; 49 } 50 for(int i=1;i<=n;i++) 51 for(int j=1;j<=n;j++){ 52 if(i==j)g[i][j]=0; 53 else if(g[i][j]==0)g[i][j]=INF; 54 } 55 prim(1); 56 } 57 }