QS Network

zoj1586:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1586

题目大意:最小生成树,不只算两点之间的费用,还要算点的费用,并不是个点只算一次费用,而是每出现一次算一次。
题解:其实只需要在算距离时,把两点的距离加入其中在排序就行了。

 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\n",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 }
View Code

 

posted on 2013-10-17 12:39  天依蓝  阅读(276)  评论(0编辑  收藏  举报

导航