想看更多的解题报告: http://iyenn.com/rec/1824570.html
转载请注明出处:http://blog.csdn.net/wangjian8006
题目大意:首先给你一个图,需要你求出最小生成树,输入N个节点,用大写字母表示了节点,然后节点与节点之间有权值。
比如有9个节点,然后接下来有n-1行表示了边的情况,拿第一行举例
A 2 B 12 I 25
表示A有两个邻点,B和I,AB权值是12,AI权值是25
解题思路:一个很直接的模板题,分别用prim和kruskal实现
- /*
- prim
- Memory 168K
- Time 0MS
- */
- #include
- using namespace std;
- #define MAXV 30
- #define inf 1<<29
-
- int map[MAXV][MAXV],n,d[MAXV],vis[MAXV];
-
- void prim(){
- int i,j,mi,v;
- for(i=0;i
- d[i]=map[0][i];
- vis[i]=0;
- }
- for(i=1;i<=n;i++){
- mi=inf;
- for(j=0;j
- if(!vis[j] && mi>d[j]){
- v=j;
- mi=d[j];
- }
- }
- vis[v]=1;
- for(j=0;j
- if(!vis[j] && d[j]>map[v][j]) //和dijstra不同的一点是这里找的是最小邻边
- d[j]=map[v][j];
- }
- for(i=1;i
0]+=d[i]; - printf("%d\n",d[0]);
- }
-
- int main(){
- int i,j,m,c;
- char a[2],b[2];
- while(scanf("%d",&n) && n){
- for(i=0;i
- for(j=0;j
- if(i==j)
- map[i][j]=0;
- else
- map[i][j]=inf;
- for(i=1;i
- scanf("%s%d ",&a,&m);
- for(j=0;j
- scanf("%s%d ",&b,&c);
- map[a[0]-'A'][b[0]-'A']=map[b[0]-'A'][a[0]-'A']=c;
- }
- }
- prim();
- }
- return 0;
- }
=======================================================================
- /*
- kruskal
- Memory 172K
- Time 0MS
- */
- #include
- using namespace std;
- #define MAXM 900
- #define MAXV 30
-
- typedef struct{
- int s,t,w;
- }Edge;
-
- int n,esum,set[MAXV];
- Edge edge[MAXM];
-
- int find(int x){
- int rt;
- if(set[x]!=x){
- rt=find(set[x]);
- set[x]=rt;
- return set[x];
- }else return x;
- }
-
- bool Union(int a,int b){
- int fa,fb;
- fa=find(a); //这里用并查集来判断是否有环
- fb=find(b);
- if(fa==fb) return 0; //构成环了,这条边不能加进来
- set[fa]=fb;
- return 1;
- }
-
- void kruskal(){
- int i,ans=0;
- for(i=0;i
- if(Union(edge[i].s,edge[i].t)){
- //如果将这条边加进来构成不了环就加进来
- //还可以加一个计数,加到n-1就退出循环,如果不足n-1就构成不了生成树
- ans+=edge[i].w;
- }
- }
- printf("%d\n",ans);
- }
-
- int cmp(const void * a,const void *b){
- return (*(Edge*)a).w-(*(Edge*)b).w;
- }
-
- int main(){
- int i,j,m,c;
- char a[2],b[2];
- while(scanf("%d",&n) && n){
- esum=0;
- for(i=0;i<=n;i++) set[i]=i;
- for(i=1;i
- scanf("%s%d ",&a,&m);
- for(j=0;j
- scanf("%s%d ",&b,&c);
- edge[esum].s=a[0]-'A';
- edge[esum].t=b[0]-'A';
- edge[esum++].w=c;
- }
- }
- qsort(edge,esum,sizeof(edge[0]),cmp); //首先对所有边的权值从小到大排序
- kruskal();
- }
- return 0;
- }
注:本文转载自blog.csdn.net的wangjian8006的文章"http://blog.csdn.net/wangjian8006/article/details/7875157"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
评论记录:
回复评论: