最小生成树练习3(普里姆算法Prim)

风萧萧兮易水寒,壮士要去敲代码。本女子开学后再敲了。。

poj1258 Agri-Net(最小生成树)水题。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 using namespace std;
 5 const int inf=0x3f3f3f3f;
 6 const int N=101;
 7 int n,m;
 8 int g[N][N],low[N];
 9 void prim(int u0){
10     int i,j,mi,v,ans=0;
11     for(i=0;i<n;++i){
12         low[i]=g[u0][i];
13     }
14     low[u0]=-1;
15     for(i=1;i<n;++i){
16         mi=inf;
17         v=-1;
18         for(j=0;j<n;++j)
19             if(low[j]!=-1&&low[j]<mi){
20                 v=j; mi=low[j];
21             }
22         ans+=low[v];
23         low[v]=-1;
24         for(j=0;j<n;++j){
25             if(g[v][j]<low[j]){
26                 low[j]=g[v][j];
27             }
28         }
29     }
30     printf("%d\n",ans);
31 }
32 int main(){
33     int t,i,j;
34     while(scanf("%d",&n)==1){
35         memset(g,inf,sizeof(inf));
36         for(i=0;i<n;++i)
37             for(j=0;j<n;++j)
38             scanf("%d",&g[i][j]);
39         prim(0);
40     }
41     return 0;
42 }

poj1751 Highways(最小生成树)水题。已修好的路赋值为0。不用sqrt计算距离,因为题目没要求。做完这题后把自学时的模板改了一点,因为一开始的模板太挫。。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cmath>
 5 using namespace std;
 6 const int inf=0x3f3f3f3f;
 7 const int N=751;
 8 int n,m;
 9 int g[N][N],low[N],near[N],x[N],y[N];
10 void prim(int u0){
11     int i,j,mi,v;
12     for(i=1;i<=n;++i){
13         low[i]=g[u0][i];
14         near[i]=u0;
15     }
16     low[u0]=-1;
17     for(i=1;i<n;++i){
18         mi=inf;
19         v=-1;
20         for(j=1;j<=n;++j)
21             if(low[j]!=-1&&low[j]<mi){
22                 v=j; mi=low[j];
23             }
24         if(mi!=0)printf("%d %d\n",near[v],v);
25         low[v]=-1;
26         for(j=1;j<=n;++j){
27             if(g[v][j]<low[j]){
28                 low[j]=g[v][j];
29                 near[j]=v;
30             }
31         }
32     }
33 }
34 int main(){
35     int t,i,j;
36     scanf("%d",&n);
37     memset(g,inf,sizeof(g));
38     for(i=1;i<=n;++i) scanf("%d%d",&x[i],&y[i]);
39     for(i=1;i<=n;++i){
40         for(j=i+1;j<=n;++j){
41             g[i][j]=g[j][i]=(x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]);
42         }
43     }
44     scanf("%d",&m);
45     while(m--){
46         scanf("%d%d",&i,&j);
47         g[i][j]=g[j][i]=0;
48     }
49     prim(1);
50     return 0;
51 }

poj1789 Truck History(最小生成树)每种卡车类型都是由其他卡车类型派生出来,第一种除外。理解:顶点为卡车类型,边的权值为类型对(t0,d0)的距离(编码中不同字符的位置数目)。。看懂题看得头疼,其实不难做。

 1 #include<cstdio>
 2 #include<cstring>
 3 using namespace std;
 4 const int inf=0x3f3f3f3f;
 5 const int N=2001;
 6 int n;
 7 char code[N][8];
 8 int g[N][N],low[N],a[N],ans;
 9 void prim(int u0){
10     int i,j,mi,v;
11     ans=0;
12     for(i=0;i<n;++i){
13         low[i]=g[u0][i];
14     }
15     low[u0]=-1;
16     for(i=1;i<n;++i){
17         mi=inf;
18         v=-1;
19         for(j=0;j<n;++j)
20             if(low[j]!=-1&&low[j]<mi){
21                 v=j; mi=low[j];
22             }
23         ans+=low[v];
24         low[v]=-1;
25         for(j=0;j<n;++j){
26             if(g[v][j]<low[j])
27                 low[j]=g[v][j];
28         }
29     }
30     printf("The highest possible quality is 1/%d.\n",ans);
31 }
32 int main(){
33     int i,j,k,d;
34     while(scanf("%d",&n),n){
35         memset(g,inf,sizeof(g));
36         for(i=0;i<n;++i) scanf("%s",code[i]);
37         for(i=0;i<n-1;++i){
38             for(j=i+1;j<n;++j){
39                 d=0;
40                 for(k=0;k<7;++k)
41                     d+=(code[i][k]!=code[j][k]);
42                 g[i][j]=g[j][i]=d;
43             }
44         }
45         prim(0);
46     }
47     return 0;
48 }

poj2349 Arctic Network(最小生成树)求出最小生成树,将边从大到小排序,前s-1条用s个卫星通信,第s大边即为答案。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cmath>
 5 using namespace std;
 6 const int inf=0x3f3f3f3f;
 7 const int N=501;
 8 int n,s;
 9 double g[N][N],low[N],d[N],x[N],y[N];
10 int cmp(int a,int b){
11     return a > b;
12 }
13 void prim(int u0){
14     int i,j,mi,v;
15     int cnt=0;
16     for(i=0;i<n;++i){
17         low[i]=g[u0][i];
18     }
19     low[u0]=-1;
20     for(i=1;i<n;++i){
21         mi=inf;
22         v=-1;
23         for(j=0;j<n;++j)
24             if(low[j]!=-1&&low[j]<mi){
25                 v=j; mi=low[j];
26             }
27         d[cnt++]=low[v];
28         low[v]=-1;
29         for(j=0;j<n;++j){
30             if(g[v][j]<low[j])
31                 low[j]=g[v][j];
32         }
33     }
34     sort(d,d+cnt,cmp);
35     printf("%.2f\n",d[s-1]);
36 }
37 int main(){
38     int t,i,j;
39     double d;
40     scanf("%d",&t);
41     while(t--){
42         memset(g,inf,sizeof(g));
43         scanf("%d%d",&s,&n);
44         for(i=0;i<n;++i) scanf("%lf%lf",&x[i],&y[i]);
45         for(i=0;i<n;++i){
46             for(j=i+1;j<n;++j){
47                 d=sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));
48                 g[i][j]=g[j][i]=d;
49             }
50         }
51         prim(0);
52     }
53     return 0;
54 }

poj3026 Borg Maze(最小生成树,bfs预处理)因为这题我几天没打码了,今天做出来感觉也不是很难。还是深感基础之弱内心痛苦。。对了,记得看discuss哦,如果你不想多挥霍青春的话。。。

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<queue>
 5 using namespace std;
 6 const int inf=0x3f3f3f3f;
 7 const int N=51;
 8 const int M=102;
 9 int x,y;
10 int n;
11 int dir[][2]={0,1,0,-1,1,0,-1,0};
12 int g[M][M],low[M];
13 char mp[N][N];
14 int G[N][N];
15 int vd[N][N];
16 void bfs(int sx,int sy){
17     queue<pair<int,int> >q;
18     while(!q.empty())q.pop();
19     memset(vd,-1,sizeof(vd));
20     vd[sx][sy]=0;
21     q.push(make_pair(sx,sy));
22     while(!q.empty()){
23         pair<int,int>u=q.front(); q.pop();
24         if(G[u.first][u.second]>0)
25             g[G[sx][sy]][G[u.first][u.second]]=vd[u.first][u.second];
26         for(int i=0;i<4;++i){
27             int xx=u.first+dir[i][0];
28             int yy=u.second+dir[i][1];
29             if(mp[xx][yy]==‘#‘||vd[xx][yy]!=-1)continue;
30                 vd[xx][yy]=vd[u.first][u.second]+1;
31                 q.push(make_pair(xx,yy));
32         }
33     }
34 }
35 void prim(int u0){
36     int i,j,mi,v,ans=0;
37     for(i=1;i<n;++i) low[i]=g[u0][i];
38     low[u0]=-1;
39     for(i=1;i<n-1;++i){
40         mi=inf;
41         v=-1;
42         for(j=1;j<n;++j)
43             if(low[j]!=-1&&low[j]<mi){
44                 v=j; mi=low[j];
45             }
46         ans+=low[v];
47         low[v]=-1;
48         for(j=1;j<n;++j){
49             if(g[v][j]<low[j]){
50                 low[j]=g[v][j];
51             }
52         }
53     }
54     printf("%d\n",ans);
55 }
56 int main(){
57     int t,i,j;
58     scanf("%d",&t);
59     while(t--){
60         scanf("%d%d",&x,&y);
61         gets(mp[0]);
62         for(i=0;i<y;++i) gets(mp[i]);
63         n=1;
64         for(i=0;i<y;++i){
65             for(j=0;j<x;++j){
66                 if(mp[i][j]==‘A‘||mp[i][j]==‘S‘)
67                     G[i][j]=n++;
68                 else G[i][j]=-1;
69             }
70         }
71         for(i=0;i<y;++i)
72             for(j=0;j<x;++j)
73             if(G[i][j]>0) bfs(i,j);
74         prim(1);
75     }
76     return 0;
77 }

时间: 2024-09-30 17:43:56

最小生成树练习3(普里姆算法Prim)的相关文章

普里姆算法-prim

算法代码: C++ Code 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 /* Prim算法生成最小生成树  */ void MiniSpanTree_Prim(MGraph MG) { int min, i, j, k; int adjvex[MAXVEX];/* 

普里姆算法(Prim)与最小生成树问题

普里姆算法 @anthor:QYX 普里姆算法在找最小生成树时,将顶点分为两类,一类是在查找的过程中已经包含在树中的(假设为 A 类),剩下的是另一类(假设为 B 类). 对于给定的连通网,起始状态全部顶点都归为 B 类.在找最小生成树时,选定任意一个顶点作为起始点,并将之从 B 类移至 A 类:然后找出 B 类中到 A 类中的顶点之间权值最小的顶点,将之从 B 类移至 A 类,如此重复,直到 B 类中没有顶点为止.所走过的顶点和边就是该连通图的最小生成树. 例如,通过普里姆算法查找图 2(a)

最小生成树(MST)----普里姆(Prim)算法与克鲁斯卡尔(Kruskal)算法

1.概念:给定一个带权的无向连通图,如何选取一棵生成树,使树上所有边上权的总和为最小,这叫最小生成树. 2.应用:例如:要在n个城市之间铺设光缆,主要目标是要使这 n 个城市的任意两个之间都可以通信,但铺设光缆的费用很高,且各个城市之间铺设光缆的费用不同,因此另一个目标是要使铺设光缆的总费用最低.这就需要找到带权的最小生成树. 3.求最小生成树的算法 3.1 普里姆(Prim)算法 方法:从指定顶点开始将它加入集合中,然后将集合内的顶点与集合外的顶点所构成的所有边中选取权值最小的一条边作为生成树

ACM第四站————最小生成树(普里姆算法)

对于一个带权的无向连通图,其每个生成树所有边上的权值之和可能不同,我们把所有边上权值之和最小的生成树称为图的最小生成树. 普里姆算法是以其中某一顶点为起点,逐步寻找各个顶点上最小权值的边来构建最小生成树. 其中运用到了回溯,贪心的思想. 废话少说吧,这个其实是一个模板,直接套用就好!直接上题吧!这些东西多练就好! 一.最小生成树: 题目描述 求一个连通无向图的最小生成树的代价(图边权值为正整数). 输入 第 一行是一个整数N(1<=N<=20),表示有多少个图需要计算.以下有N个图,第i图的第

数据结构例程——最小生成树的普里姆算法

本文是[数据结构基础系列(7):图]中第11课时[最小生成树的普里姆算法]的例程. (程序中graph.h是图存储结构的"算法库"中的头文件,详情请单击链接-) #include <stdio.h> #include <malloc.h> #include "graph.h" void Prim(MGraph g,int v) { int lowcost[MAXV]; //顶点i是否在U中 int min; int closest[MAXV]

数据结构(五)图---最小生成树(普里姆算法)

一:最小生成树 (一)定义 我们把构造连通网的最小代价生成树称为最小生成树 (二)什么是最小生成树? 1.是一棵树 1)无回路 2)N个顶点,一定有N-1条边 2.是生成树 1)包含全部顶点 2)N-1条边都在图中 3.边的权重和最小 (三)案例说明 在实际生活中,我们常常碰到类似这种一类问题:如果要在n个城市之间建立通信联络网, 则连通n个城市仅仅须要n-1条线路.这时.我们须要考虑这样一个问题.怎样在最节省经费前提 下建立这个通信网.换句话说,我们须要在这n个城市中找出一个包括全部城市的连通

图-&gt;连通性-&gt;最小生成树(普里姆算法)

文字描述 用连通网来表示n个城市及n个城市间可能设置的通信线路,其中网的顶点表示城市,边表示两城市之间的线路,赋于边的权值表示相应的代价.对于n个定点的连通网可以建立许多不同的生成树,每一棵生成树都可以是一个通信网.现在,我们要选择这样一个生成树,使总的耗费最少.这个问题就是构造连通网的最小代价生成树(Minimum Cost Spanning Tree: 最小生成树)的问题.一棵生成树的代价就是树上各边的代价之和. 有多种算法可以构造最小生成树,其他多数都利用的最小生成的MST(minimum

数据结构之最小生成树(普里姆算法)

1)普里姆算法 可取图中任意一个顶点v作为生成树的根,之后若要往生成树上添加顶点w,则在顶点v和顶点w之间必定存在一条边,并且 该边的权值在所有连通顶点v和w之间的边中取值最小.一般情况下,假设n个顶点分成两个集合:U(包含已落在生成树上 的结点)和V-U(尚未落在生成树上的顶点),则在所有连通U中顶点和V-U中顶点的边中选取权值最小的边. 例如:起始生成树上面就一个顶点.为了连通两个集合,在可选的边中,选择权值最小的.需要辅助数组,V-U中所有顶点. 具体实例如下图所示:求下图的最小生成树 我

数据结构-最小生成树-普里姆算法

转自https://blog.csdn.net/ZGUIZ/article/details/54633115 首先仍然是预定义: 1 #define OK 1 2 #define ERROR 0 3 #define Max_Int 32767 4 #define MVNum 100 5 6 typedef int Status; 7 typedef char VerTexType; 8 typedef int ArcType; 9 10 struct{ 11 VerTexType adjvex;