NYOJ 38布线问题

http://acm.nyist.net/JudgeOnline/problem.php?pid=38

布线问题

时间限制:1000 ms  |  内存限制:65535 KB
难度:4
 
描述
南阳理工学院要进行用电线路改造,现在校长要求设计师设计出一种布线方式,该布线方式需要满足以下条件:
1、把所有的楼都供上电。
2、所用电线花费最少
 
输入
第一行是一个整数n表示有n组测试数据。(n<5)
每组测试数据的第一行是两个整数v,e.
v表示学校里楼的总个数(v<=500)
随后的e行里,每行有三个整数a,b,c表示a与b之间如果建铺设线路花费为c(c<=100)。(哪两栋楼间如果没有指明花费,则表示这两栋楼直接连通需要费用太大或者不可能连通)
随后的1行里,有v个整数,其中第i个数表示从第i号楼接线到外界供电设施所需要的费用。( 0<e<v*(v-1)/2 )
(楼的编号从1开始),由于安全问题,只能选择一个楼连接到外界供电设备。
数据保证至少存在一种方案满足要求。
输出
每组测试数据输出一个正整数,表示铺设满足校长要求的线路的最小花费。
样例输入
1
4 6
1 2 10
2 3 10
3 1 10
1 4 1
2 4 1
3 4 1
1 3 5 6
样例输出
4

思路:prim算法水题。
 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 #include<string.h>
 4 #define inf 0xfffff
 5 int g[501][501];
 6 int lowcost[250000],used[250000],closet[250000];
 7 int ans;
 8 void prim(int n,int a)
 9 {
10     int i,k,j,min;
11     memset(used,0,sizeof(used));
12     for(i=1;i<=n;i++)
13     {
14         lowcost[i]=g[i][a];
15         closet[i]=a;
16     }
17     //for(i=1;i<=n;i++)
18     //{
19         //printf("lowcoset[%d]=%d ",i,lowcost[i]);
20     //}
21     //printf("
");
22     used[a]=1;
23     for(i=1;i<=n;i++)
24     {
25         min=inf;
26         j=a;
27         for(k=1;k<=n;k++)
28         {
29             if(lowcost[k]<min&&!used[k])
30             {
31                 min=lowcost[k];
32                 j=k;
33             }
34         }
35         used[j]=1;        
36         ans+=g[j][closet[j]];
37         //printf("j=%d ans=%d
",j,ans);
38         for(k=1;k<=n;k++)
39         {
40             if(lowcost[k]>g[k][j]&&!used[k])
41             {
42                 lowcost[k]=g[k][j];
43                 closet[k]=j;
44             }
45         }
46     }
47     
48 }
49 int main()
50 {
51     int t,i,j,a,b,c,n,v,min,e;
52     scanf("%d",&t);
53     while(t--)
54     {
55         min=inf;
56         ans=0;
57         scanf("%d %d",&v,&e);
58         for(i=1;i<=v;i++)
59         {
60             for(j=1;j<=v;j++)
61             g[i][j]=inf;
62             g[i][i]=0;
63         }
64         for(i=1;i<=e;i++)
65         {
66             scanf("%d %d %d",&a,&b,&c);
67             if(g[a][b]>c)
68             g[a][b]=g[b][a]=c;
69         }
70         /*for(i=1;i<=v;i++)
71         {
72             for(j=1;j<=v;j++)
73             {
74                 printf("%5d ",g[i][j]);
75             }
76             printf("
");
77         }*/
78         for(i=1;i<=v;i++)
79         {
80             scanf("%d",&a);
81             if(a<min)
82             {
83               min=a;
84               j=i;
85             }
86         }
87         prim(v,j);
88         printf("%d
",ans+min);        
89     }
90     return 0;
91 }
View Code
原文地址:https://www.cnblogs.com/zeze/p/nyoj38.html