1.链接地址:
http://bailian.openjudge.cn/practice/1251/
http://poj.org/problem?id=1251
2.题目:
- 总时间限制:
- 1000ms
- 内存限制:
- 65536kB
- 描述
热 带岛屿Lagrishan的首领现在面临一个问题:几年前,一批外援资金被用于维护村落之间的道路,但日益繁茂的丛林无情的侵蚀着村民的道路,导致道路维 修开销巨大,长老会不得不放弃部分道路的维护。上图左侧图显示的是正在使用道路的简图以及每条路每个月的维修费用(单位为aacms)。现在长老会需要提 出一种方案,即需要保证村落之间都可以互相到达,又要将每个月的道路维修费用控制在最小。村子编号为从A到I。上图右侧显示的方案最小维修开销为216 aacms每月。
- 输入
- 输入包含1~100个数据集,最后一行为0.每个数据集第一行为村落数目n, 1 < n < 27,依次用字母表的前n个字母标记。接下来有n-1行,每行的第一个数据便是按字母顺序排列的村子编号(不包括最后一个村庄)。每个村庄后面的数据k代 表该村庄通往编号在其之后的村庄的道路数目,如A 2 B 12 I 25,代表A村庄有2个编号在A之后的村庄和其相连。若k大于0,k后面会依次给出这k个村庄的编号以及各自到起始村庄的道路维修费用,如A 2 B 12 I 25,代表A和B之间道路维修费用为12, A和I之间道路维修费用为25(维修费用为不超过100的正整数).路的总数目不超过75条,每个村庄到其他村庄不会有超过15条路(包括编号在其之前和 之后的)。
- 输出
- 每个数据集有一个输出:针对解决方案每个月维修道路的小费用。
提示:蛮力算法虽能找出解决方案,但将会超出时间限制。- 样例输入
9 A 2 B 12 I 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- 样例输出
216 30
3.思路:
4.代码:
1 #include<stdio.h> 2 #include<iostream> 3 #define MAX 30 4 #define MAXLOW 9999999 5 using namespace std; 6 struct 7 { 8 int lowcost; 9 }closedge[MAX]; 10 int G[MAX][MAX]; 11 /*int minimum(int size) 12 { 13 //在g[][]已经init的前提下 14 int i,min; 15 for(i=0;i<size;i++) 16 { 17 if(closedge[i].lowcost>0) 18 { 19 min=i; 20 break; 21 } 22 } 23 for(i=i;i<size;i++) 24 { 25 if(closedge[i].lowcost>0&&closedge[i].lowcost<closedge[min].lowcost) 26 { 27 min=i; 28 } 29 } 30 return min; 31 }*/ 32 int minimum(int size) 33 { 34 int i,min,min_num=MAXLOW; 35 for(i=0;i<size;i++) 36 { 37 if(closedge[i].lowcost!=0 && closedge[i].lowcost<min_num) 38 { 39 min_num=closedge[i].lowcost; 40 min=i; 41 } 42 } 43 return min; 44 } 45 int MiniSpanTree_PRIM(int G[][MAX],int k,int size) 46 { 47 48 int count=0; 49 int i,j; 50 //初始化辅助数组 51 for(j=0;j<size;j++) 52 { 53 if(j!=k) closedge[j].lowcost=G[k][j]; 54 } 55 closedge[k].lowcost=0;//初始,U={start} 56 //测试辅助数组是否正确 57 /*for(j=0;j<size;j++) 58 { 59 cout<<closedge[j].lowcost<<" "; 60 } 61 cout<<endl;*/ 62 for(i=1;i<size;i++) 63 { 64 k=minimum(size); 65 count+=closedge[k].lowcost; 66 closedge[k].lowcost=0; 67 for(j=0;j<size;j++) 68 { 69 if(G[k][j]<closedge[j].lowcost) 70 { 71 closedge[j].lowcost=G[k][j]; 72 } 73 } 74 /*for(j=0;j<size;j++) 75 { 76 cout<<closedge[j].lowcost<<" "; 77 } 78 cout<<endl;*/ 79 } 80 return count; 81 } 82 void InitGraph(int G[][MAX]) 83 { 84 int i,j; 85 for(i=0;i<MAX;i++) 86 { 87 for(j=0;j<MAX;j++) 88 { 89 G[i][j]=MAXLOW; 90 } 91 } 92 } 93 int findStart(int G[][MAX],int size) 94 { 95 int i,j; 96 for(i=0;i<size;i++) 97 { 98 for(j=0;j<size;j++) 99 { 100 if(G[i][j]!=MAXLOW) return i; 101 } 102 } 103 } 104 int main() 105 { 106 int size; 107 int m,n,num,cost; 108 int i,j; 109 char c1,c2; 110 //size为村庄数 111 while(scanf("%d",&size)!=EOF && size) 112 { 113 //m为第几个村庄 114 InitGraph(G); 115 /*for(m=0;m<size-1;m++) 116 { 117 //num为村庄的路的数量(不完全的) 118 cin>>i>>num; 119 for(n=0;n<num;n++) 120 { 121 cin>>j>>cost; 122 G[i-'A'][j-'A']=G[j-'A'][i-'A']=cost; 123 } 124 }*/ 125 for(i=0;i<size-1;i++) 126 { 127 cin>>c1>>n; 128 for(j=0;j<n;j++) 129 { 130 cin>>c2>>num; 131 G[c1-'A'][c2-'A']=G[c2-'A'][c1-'A']=num; 132 } 133 } 134 //make sure input 135 /*for(i=0;i<size;i++) 136 { 137 for(j=0;j<size;j++) 138 { 139 cout<<G[i][j]<<" "; 140 } 141 cout<<endl; 142 }*/ 143 cout<<MiniSpanTree_PRIM(G,findStart(G,size),size)<<endl; 144 //cout<<findStart(G,size)<<size<<endl;测试找边是否正确 145 } 146 147 return 1; 148 }