图论之最小生成树
来源:互联网 发布:中国社交网络使用排名 编辑:程序博客网 时间:2024/06/01 08:00
这次的生成树是匆忙写出来的,所以代码有点难看!我用的是kruskal算法,我认为这个比prim算法好理解一点!就是每次找未知边的最小边,在判断此边的两个点在已知边下是否连通——这里就要用到我刚说的不相交集类,如果连通则放弃,不连通则加人以知边,做完N-1次即可,下面是代码:
#include<iostream>#include<stdio.h>#include<vector>#include<queue>using namespace std;class Disjsets{private:vector<int>s;public:Disjsets(int num):s(num){for(int i=0;i<s.size();i++)s[i]=-1;}int find(int x){if(s[x]<0)return x;elsereturn s[x]=find(s[x]);}void unionSets(int root1,int root2){if(s[root1]<s[root2])s[root1]=root2;else{if(s[root1]==s[root2])s[root1]--;s[root2]=root1;}}void makeDisj(){for(int i=0;i<s.size();i++)s[i]=-1;}};class graph{ struct Edge{ int e1,e2,w; Edge(int u,int v,int w):e1(u),e2(v),w(w){} friend bool operator <(Edge v1,Edge v2) { return v1.e1>v2.e1; } }; struct weight{int ver;int num;int w;weight(){};weight(int v,int n,int ww=0):ver(v),num(n),w(ww){} friend bool operator <(const weight v,const weight v1){ returnv.w>v1.w;} }; class vertex{public:int num; //点在图中的编号vector<weight>L; //与此顶点相关的边vertex():num(0){}void merge(int x,int y){ weight p(num,x,y); L.push_back(p);}};vector<vertex> v;public:graph(int x){v.resize(x);for(int i=0;i<x;i++)v[i].num=i+1;}void merge(int x,int y,int weight){if(x!=y)v[x-1].merge(y,weight);}int kruskal(){priority_queue<weight>qw;priority_queue<Edge>Ed;int n=v.size();Disjsets D(n+1);int e1,e2,sum=0;for(int i=0;i<n;i++) { int siz=v[i].L.size(); for(int j=0;j<siz;j++){ weight tmp=v[i].L[j]; qw.push(tmp);} }weight wg;int edge =1;for(;edge<n&&!qw.empty();edge++){while(D.find(qw.top().num)==D.find(qw.top().ver)) { qw.pop(); if(qw.empty()) return -1; }wg=qw.top(); e1=wg.ver; e2=wg.num; sum+=wg.w; qw.pop(); Edge E(e1,e2,wg.w); Ed.push(E); D.unionSets(e1,e2); } if(edge==n) {while(!Ed.empty()){Edge ed=Ed.top();Ed.pop();cout<<"("<<ed.e1<<","<<ed.e2<<","<<ed.w<<") ";}cout<<endl; return sum; } return -1; }};int main(){ freopen("in.txt","r",stdin); freopen("out.txt","w",stdout); int n,m; while(cin>>m>>n&&m) { graph G(n); int u,v,w; while(m--) { cin>>u>>v>>w; G.merge(u,v,w); G.merge(v,u,w); } int sum=G.kruskal(); sum==-1?cout<<"?"<<endl:cout<<sum<<endl; } fclose(stdin); fclose(stdout); return 0;}然后是in.txt的数据:
12 7
1 2 2
1 4 1
2 4 3
2 5 10
3 1 4
3 5 6
4 6 8
4 7 4
4 5 2
4 3 2
5 7 6
7 6 1
12 7
1 4 1
1 2 2
1 3 4
2 4 3
2 5 10
3 4 2
3 6 5
4 5 7
4 6 8
4 7 4
5 7 6
6 7 1
3 3
1 2 1
1 3 2
2 3 4
1 3
2 3 2
0 100
最后是out.txt的结果:
(1,4,1) (1,2,2) (4,3,2) (4,7,4) (4,5,2) (7,6,1)
12
(1,4,1) (1,2,2) (4,3,2) (4,7,4) (7,6,1) (7,5,6)
16
(1,2,1) (1,3,2)
3
?
结果OK ,另外,交hdu的畅通工程那题也是ac的,说明确实没有问题!
6 0
- 图论之最小生成树
- UVa1395图论之最小生成树
- 图论之最小生成树
- 图论算法之最小生成树
- 图论之最小生成树
- 图论之最小生成树-Conscription
- 图论之最小生成树
- 图论之最小生成树
- 图之最小生成树
- 图论之最小生成树(Prim普里姆算法)
- 图论浅析--最小生成树之Prim
- 图论浅析--最小生成树之Kruskal
- 图论之最小生成树-Agri-Net
- 图之三(最小生成树)
- 数据结构之 图的最小生成树
- 图算法之最小生成树(Kruskal)
- 十七、图算法之最小生成树
- 图之 最小生成树 Prim算法
- ios下拉刷新
- COCOS2DX 动画
- [新技术]10 个顶级 JavaScript 库(转载)
- C语言编程过程详解
- 第三周作业
- 图论之最小生成树
- 排列公式
- 实现调用Android手机的拍照功能
- 我对搜索算法的一点点理解
- Struts中的namespace
- 猜随机数
- archlinux 2014.03.01 硬盘安装 win + grub4dos + arch
- hdu 1114
- LeetCode problem 2: Evaluate Reverse Polish Notation