图论算法之最小生成树
2016-04-07 21:35
435 查看
1.最小生成树(Prim算法)普里姆算法,一般针对的是无向图,而且其是连通的
2. 最小生成树(Kruskal 算法)克鲁斯卡尔算法
上述两种算法都是贪婪算法
#include<iostream> #include<vector> #include<algorithm> using namespace std; const int N=100; const int MAX=100000; bool visit ; int d ,path ; struct Node{ int v,w;//这里w代表权值 Node* next; Node(int x,int y):v(x),w(y),next(0){}//参数初始化表 }; struct Graph{ int E,V; Node* Adj ;//邻接表 }; //无向图 void CreateGraph(Graph &G){ cin>>G.V>>G.E; for(int i=0;i<G.V;++i) //顶点数小于N G.Adj[i]=NULL; for(int i=0;i<G.E;++i){//边数 int u,v,w; cin>>u>>v>>w; Node* p=new Node(u,w); p->next=G.Adj[v]; G.Adj[v]=p; p=new Node(v,w); p->next=G.Adj[u]; G.Adj[u]=p;//w代表边<u,v>的权值 } } int cmp(int x,int y){ return d[x]<d[y];//当此不等式成立时,x,y的排序是xy,否则为yx } int min(int x,int y){ return x>y?y:x; } int Prim(Graph &G, int s){ Node* p; vector<int> q; for(int i=0;i<G.V;++i){ visit[i]=false; d[i]=MAX; path[i]=-1; q.push_back(i); } d[s]=0; while(!q.empty()){ sort(q.begin(),q.end(),cmp); int u=q[0]; visit[u]=true; q.erase(q.begin()); for(p=G.Adj[u];p;p=p->next) { int v=p->v; if(!visit[v]){ d[v]=min(d[v],p->w); if(d[v]==p->w) path[v]=u; } } } int result=0; for(int i=0;i<G.V;++i){ result+=d[i];} return result; } int main(){ Graph G; CreateGraph(G); cout<<Prim(G, 0); return 0; }这里的排序准则cmp,是将元素按其d[ ]的从小到大排序。
2. 最小生成树(Kruskal 算法)克鲁斯卡尔算法
#include<iostream> #include<vector> #include<algorithm> using namespace std; const int n=12, m=7; //m是顶点数,n是边数 struct Edge{ int v,u,w;//这里w是边<v,u>的权重 //Edge(int x,int y,int z):v(x),u(y),w(z){} }; int cmp(Edge x, Edge y){ return x.w<y.w; } int p[m];//并查集 void MakeSet(int x){ p[x]=-1;//各树的初始高度是-1,这里-1仅仅是个假设的初始值,不设为0,是因为顶点是0,...,m-1; } int Find(int x){ if(p[x]<=-1) return x; else return Find(p[x]); } void Union(int x, int y){ p[x]=y; if(p[x]<p[y]) //按高度合并 p[y]=x; //将以y为根的树合并在以x为根的树上 else{ if(p[x]==p[y]) p[y]--; p[x]=y; } } int Kruskal(Edge* e){//n为边数,m为顶点数 for(int i=0;i<m;++i) MakeSet(i); int result=0; sort(e,e+n,cmp); for(int i=0;i<n;++i){ if(Find(e[i].v)!=Find(e[i].u)){ Union(Find(e[i].v),Find(e[i].u)); cout<<e[i].v<<e[i].u<<e[i].w<<endl; result+=e[i].w; } } return result; } int main(){ int v,u,w; Edge e ; for(int i=0;i<n;++i){ cin>>v>>u>>w; e[i].v=v; e[i].u=u; e[i].w=w; } cout<<Kruskal(e)<<endl; return 0; }
上述两种算法都是贪婪算法
相关文章推荐
- DOM XSS的原理与防护
- nginx 301跳转到带www域名方法rewrite(转)
- 文章内容页图片自动居中,自适应手机,宽度100%
- 数据结构(8):二叉树的存储结构
- FFMpeg处理RTMP流的总结
- 树形dp-hdu1561
- git安装及常用命令
- requireJS学习
- 关于intent.setFlags()的一些故事
- 构建之法第八章读后感与团队项目的一些想法
- 实现大数四则运算
- HNOI2016上半场考试总结
- Bigger is Better
- linux下ftp服务器ARM移植
- ps树叶的雕刻
- 去除listview和gridview的点击效果
- 【USACO题库】2.4.1 The Tamworth Two两只塔姆沃斯牛
- Spring MVC DispatcherServlet配置
- PAT 1002. 写出这个数 (20)
- Jquery判断数组中是否包含某个元素$.inArray()的用法