这个题目属于最小生成树问题,可以用Prim,也可以用Kruskal(还没试)。题意简单直接,给你一个图,求出它最小生成树的权值。
题目最有趣的地方就是图的顶点是字母,稍微处理一下就好了。
Sample Input
9 //顶点个数,0时结束
A 2 B 12 I 25 //每个顶点与后面N个顶点连通 后面N组是顶点编号和权值 比如这组就是A与后面两个顶点(B,I)连通,其中AB=12,AI=25
B 3 C 10 H 40 I 8
C 2 D 18 G 55
D 1 E 44
E 2 F 60 G 38
F 0
G 1 H 35
H 1 I 35
3
A 2 B 10 C 40
B 1 C 20
0
Sample Output
216
30
套的模板吧,也没什么好说的。回头用Kruskal试试。
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #define INF 0x3f3f3f3f 5 using namespace std; 6 7 int G[30][30],dis[30],flag[30]; 8 9 int N,T,l,i,j,k,ans,minx; 10 11 char A,a; 12 13 void init() 14 { 15 memset(G,INF,sizeof(G)); 16 memset(flag,0,sizeof(flag)); 17 } 18 19 void Prim() 20 { 21 ans=0; 22 G[0][0]=0; 23 for(i=0;i<N;i++) 24 dis[i]=G[0][i]; 25 flag[0]=1; 26 for(i=1;i<N;i++) 27 { 28 minx=INF; 29 k=0; 30 for(j=0;j<N;j++) 31 { 32 if(!flag[j]&&dis[j]<minx) 33 { 34 minx=dis[j]; 35 k=j; 36 } 37 } 38 flag[k]=1; 39 ans+=minx; 40 for(j=0;j<N;j++) 41 { 42 if(!flag[j]&&dis[j]>G[k][j]) 43 dis[j]=G[k][j]; 44 } 45 } 46 cout<<ans<<endl; 47 } 48 49 int main() 50 { 51 while((cin>>N),N) 52 { 53 init(); 54 for(i=1;i<N;i++) 55 { 56 cin>>A>>T; 57 while(T--) 58 { 59 cin>>a>>l; 60 if(G[A-‘A‘][a-‘A‘]>l) 61 G[A-‘A‘][a-‘A‘]=G[a-‘A‘][A-‘A‘]=l;//A点编号为0 62 } 63 } 64 Prim(); 65 } 66 return 0; 67 }
时间: 2024-10-10 12:40:09