标签:i++ sha sizeof hot ddl 循环 lag printf --
最小生成树
一个有 n 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n 个结点,并且有保持图连通的最少的边。最小生成树可以用kruskal(克鲁斯卡尔)算法或prim(普里姆)算法求出。
热带岛屿Lagrishan的首领现在面临一个问题:几年前,一批外援资金被用于维护村落之间的道路,但日益繁茂的丛林无情的侵蚀着村民的道路,导致道路维修开销巨大,长老会不得不放弃部分道路的维护。上图左侧图显示的是正在使用道路的简图以及每条路每个月的维修费用(单位为aacms)。现在长老会需要提出一种方案,即需要保证村落之间都可以互相到达,又要将每个月的道路维修费用控制在最小。村子编号为从A到I。上图右侧显示的方案最小维修开销为216 aacms每月。
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
1 #include<stdio.h> 2 #include<string.h> 3 #include<algorithm> 4 using namespace std; 5 6 struct node{ 7 int u,v; 8 int w; 9 bool operator < (const node & a) const{ 10 return w<a.w; 11 } 12 }edge[80]; 13 int fa[30]; 14 int n,cnt; 15 16 int getfa(int x){ 17 return fa[x]=fa[x]==x?x:getfa(fa[x]); 18 } 19 20 void add(int x,int y,int w){ 21 edge[++cnt].u=x; 22 edge[cnt].v=y; 23 edge[cnt].w=w; 24 } 25 26 int kruskal(){ 27 int ans=0,cnt1=0; 28 sort(edge+1,edge+cnt+1); 29 30 for(int i=1;i<=cnt;i++){ 31 int u=getfa(edge[i].u),v=getfa(edge[i].v); 32 if(u!=v){ 33 ans+=edge[i].w; 34 fa[getfa(u)]=getfa(v); 35 if(++cnt1==n-1)break;//所有点全部连通 36 } 37 } 38 return ans; 39 } 40 41 int main(){ 42 while(scanf("%d",&n)&&n!=0){ 43 cnt=0; 44 memset(fa,0,sizeof(fa)); 45 memset(edge,0,sizeof(edge)); 46 for(int i=1;i<=n;++i)fa[i]=i; 47 for(int i=1;i<n;++i){ 48 char c[3];int x; 49 scanf("%s%d",&c,&x); 50 if(x>0) 51 for(int j=1;j<=x;++j){ 52 int y;char a[3]; 53 scanf("%s%d",&a,&y); 54 add(c[0]-64,a[0]-64,y); 55 } 56 } 57 printf("%d\n",kruskal()); 58 } 59 return 0; 60 }
#图# #最小生成树# #kruskal# ----- 丛林中的路
标签:i++ sha sizeof hot ddl 循环 lag printf --
原文地址:http://www.cnblogs.com/wjting/p/6022530.html