数据结构上机题目--MST
2013-10-28 16:38
676 查看
prim算法
kruscal算法
/************************************************************************* * author:crazy_石头 * algorithm:prim * date:2013/09/29 * 程序功能:MST * 算法流程:1.先选取一个点作起始点,然后选择它邻近的权值最小的点 (如果有多个与其相连的相同最小权值的点,随便选取一个)。如1作为起点。 2.再在伸延的点找与它邻近的两者权值最小的点。 **************************************************************************/ #include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <climits> #include <time.h> #include <queue> #include <algorithm> using namespace std; #define A system("pause") #define N 100005 #define M 400010 #define INF INT_MAX const int maxn=1000; int dis[maxn],vis[maxn],pre[maxn]; int map[maxn][maxn]; //记录路径或者说是加入的边; int n,e;//顶点数和边数; int a,b; inline int prim() { int i,j,pos,res=0; int cnt=1; for(i=1;i<=n;i++) dis[i]=map[1][i],pre[i]=1; memset(vis,0,sizeof(vis)); vis[1]=1; dis[1]=0; for(j=1;j<=n;j++) { int minm=INF; for(i=1;i<=n;i++) { if(!vis[i]&&minm>dis[i]) { minm=dis[i]; pos=i;//第一次找出最短距离及对应的点; a=i,b=pre[i]; } } vis[pos]=1; if(minm==INF) break; res+=minm; printf("(%d,%d)\n",b,a); for(i=1;i<=n;i++) { if(!vis[i]&&map[pos][i]!=INF&&map[pos][i]<dis[i]) { dis[i]=map[pos][i]; pre[i]=pos; } } } return res; } int main() { cin>>n>>e; for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { i==j?map[i][j]=0:map[i][j]=INF; } } while(e--) { int a,b,cost; cin>>a>>b>>cost; map[a][b]=map[b][a]=cost; } int ans=prim(); for(int i=1;i<=n;i++) printf("dis[%d]==%d \n",i,dis[i]); printf("weight: %d\n",ans); return 0; } /*test: 6 10 1 2 6 1 4 5 1 3 1 2 3 5 2 5 3 3 5 6 3 6 4 4 6 2 5 6 6 3 4 5 output:15 */
kruscal算法
/************************************************************************* * author:crazy_石头 * algorithm:Kruscal * date:2013/09/29 * 程序功能:MST * 算法流程:初始时全为孤立的点,图的边就绪状态为非降序排列。然后一次遍历图中的所有边(u, v), 使用并查集的思想,find_set(u)如果不等于find_set(v),也就是u和v不在同一个集合中, 那么相当于判断了添加了边(u, v)不会成环,同时合并u和v(使用union_set(u, v)). 当所有的顶点都添加到集合中去了,算法完毕。 **************************************************************************/ #include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> #include <climits> #include <time.h> #include <queue> #include <algorithm> using namespace std; #define C system("pause") #define INF INT_MAX const int maxn=1000; int p[maxn]; int n,e; struct Edge { int a; int b; int weight; bool operator<(const Edge &A)const { return weight<A.weight; } }edge[maxn*maxn]; inline int Find_set(int x) { return p[x]==-1?x:p[x]=Find_set(p[x]);//未带路径压缩; } int main() { int ans=0,cnt=0; cin>>n>>e; for(int i=0;i<e;i++) { cin>>edge[i].a>>edge[i].b>>edge[i].weight; } sort(edge,edge+e); memset(p,-1,sizeof(p)); for(int i=0;i<e;i++) { if(cnt==n-1) break; int a=Find_set(edge[i].a); int b=Find_set(edge[i].b); printf("edge[%d].a==%d\tedge[%d].b==%d\ta==%d b==%d,<%d,%d>edge[%d].cost==%d\n",i,edge[i].a,i,edge[i].b,a,b,a,b,i,edge[i].weight); if(a!=b) { cnt++; p[a]=b; ans+=edge[i].weight;//有一条边并查集找到根后,a==b,continue掉了,所以共5条边六个顶点时完成算法; printf("应该加入的边为<%d,%d>\n",edge[i].a,edge[i].b); printf("当前的ans==%d\n",ans); } else continue; } printf("%d\n",ans); return 0; } /*test: 6 10 1 2 6 1 4 5 1 3 1 2 3 5 2 5 3 3 5 6 3 6 4 4 6 2 5 6 6 3 4 5 output:15 */
相关文章推荐
- 数据结构上机题目--搜索
- 数据结构上机题目--离散时间模拟(银行等待问题)
- 数据结构上机题目4--后缀表达式求值
- 数据结构上机题目3--学生信息排序
- 数据结构上机题目2--快排
- 数据结构上机题目1--基本排序
- 分区表是硬盘的重要数据结构,管理整个硬盘空间
- 【数据结构】第1周 线性表 4:放苹果
- 【数据结构】第1周 线性表 3:位查询
- 【数据结构】第1周 线性表 2:字符串插入
- 【数据结构】第1周 线性表 1:多项式加法
- 数据结构复习纲要
- 数据结构(java)_数组顺序查找
- 用java源代码学数据结构<四>: LinkedList 详解
- 数据结构与算法实验题6.1 鼹鼠掘土挑战赛
- 判断循环队列是满还是空
- NameNode和DataNode中重要的数据结构解析
- 2013hpuacm第八周周赛题
- 大话数据结构十二:字符串的模式匹配(BM算法)
- 数据结构-单链表排序遇到的一个问题