C++,Kruskal克鲁斯卡尔算法求最小生成树
2018-06-17 23:31:27来源:未知 阅读 ()
第一篇博客。
克鲁斯卡尔求最小生成树思想:首先将n个点看做n个独立的集合,将所有边快排(从小到大)。然后,按排好的顺序枚举每一条边,判断这条边连接的两个点是否属于一个集合。若是,则将这条边加入最小生成树,并将两个点所在的集合合并为一个集合。若否,则跳过。直到找到n-1条边为止。
#include<iostream> #include<algorithm> using namespace std; struct point{ int x; int y; int v; }; //写结构体用来构造边 point a[10000];//存边 int cmp(const point &a,const point &b){ if(a.v<b.v) return 1; else return 0; }//快排要用到的比较函数 ,从小到大 int fat[101]; int father(int x){ if(fat[x]!=x) return fat[x]=father(fat[x]); else return fat[x]; }//找出一个点属于哪个集合(找这个点的爹) void unionn(int x,int y){ int fa=father(x); int fb=father(y); if(fa!=fb) fat[fa]=fb; }//将被边连接的两个独立集合合并 int main(){ int i,j,n,m,k=0,ans=0,cnt=0; cin>>n; for(i=1;i<=n;i++) for(j=1;j<=n;j++) { cin>>m; if(m!=0){ k++; a[k].x=i; a[k].y=j; a[k].v=m; } }//输入,存边 sort(a+1,a+1+k,cmp);//快排所有边 for(i=1;i<=n;i++){ fat[i]=i; }//初始化,将每个点看做独立集合 for(i=1;i<=k;i++){ if(father(a[i].x)!=father(a[i].y)){//如果这条边连接的两个点属于不同集合 ans+=a[i].v;//将这条边加入最小生成树 unionn(a[i].x,a[i].y);//将两个点所在的集合合并为一个集合 cnt++;//计数已添加的边 } if(cnt==n-1) break;//当已经有n-1条边的时候,结束 } cout<<ans; return 0; }
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- C++ 转换函数搭配友元函数 2020-06-10
- C++ 自动转换和强制类型转换(用户自定义类类型) 2020-06-10
- C++ rand函数 2020-06-10
- C++ 友元函数 2020-06-10
- C++ 运算符重载 2020-06-10
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash