http://acm.sdut.edu.cn/sdutoj/showproblem.php?pid=2144&cid=1186
最小生成树,最重要的是了解思想
稠密图用Prim,稀疏图用Kruskal
K(每次找最小的边连接,一条边连接两个点,所以单路就可以了)
1 #include<stdio.h> 2 #include<string.h> 3 #include<stdlib.h> 4 int bin[110]; 5 struct node 6 { 7 int u,v,w; 8 }q[10001]; 9 10 int cmp(const void *a,const void *b)//按距离从小到大排序 11 { 12 return (*(node *)a).w-(*(node *)b).w; 13 } 14 int find(int a) 15 { 16 if(a==bin[a]) 17 return a; 18 else 19 bin[a]=find(bin[a]); 20 }; 21 int main() 22 { 23 int n,m,i,j,sum,num; 24 int x,y; 25 while(~scanf("%d%d",&n,&m)) 26 { 27 sum=0; num=0; 28 for(i=1; i<=n; i++) 29 bin[i]=i; 30 for(i=0; i<=m-1; i++) 31 scanf("%d%d%d",&q[i].u,&q[i].v,&q[i].w); 32 qsort(q,m,sizeof(q[0]),cmp); 33 这是重点思想 for(i=0; i<=m-1; i++) 34 { 35 x=find(q[i].u); y=find(q[i].v); 36 if(x!=y) //检查是否连通 37 { 38 sum+=q[i].w;//没连通的话加上距离 39 num++; //城市+1 40 bin[x]=y; 41 } 42 if(num==n-1) 43 break; 44 } 45 printf("%d\n",sum); 46 } 47 }
Prim()
- #include <stdio.h>
- #include <string.h>
- #define N 1000001
- int map[110][110];
- int vis[110];
- int dis[110];
- int n,m;
- void prim()
- {
- int ans=0;
- int i,j;
- memset(vis,0,sizeof(vis));
- memset(dis,0,sizeof(dis));
- for(i = 1; i <= n; i++)
- dis[i] = map[1][i];
- vis[1] = 1;
- for(i = 1; i <= n-1; i++)
- {
- int pos;
- int min;
- min = N;
- for(j = 1; j <= n; j++)
- {
- if(vis[j]==0&&min>dis[j])
- {
- pos=j;
- min=dis[j];
- }
- }
- vis[pos] = 1;
- ans += min;
- for(j = 1; j <= n; j++)
- {
- if(vis[j]==0&& dis[j]>map[pos][j])
- dis[j]=map[pos][j];
- }
- }
- printf("%d\n",ans);
- return ;
- }
- int main()
- {
- int a,b,c;
- int i,j;
- while(scanf("%d %d",&n,&m)!=EOF)
- {
- for(i=1; i<=n; i++)
- {
- for(j=1; j<=n; j++)
- {
- map[i][j]=N;
- map[j][i]=N;
- }
- map[i][i]=0;
- }
- for(i=1;i<=m;i++)
- {
- scanf("%d%d%d",&a,&b,&c);
- if(c<map[a][b])
- {
- map[a][b]=c;
- map[b][a]=c;
- }
- }
- prim();
- }
- return 0;
- }
最小生成树(kruskal模版 Prim模板),布布扣,bubuko.com
时间: 2024-12-20 11:46:32