最小生成树(prim算法和kruskal算法)
学习博客:https://www.cnblogs.com/zhangming-blog/p/5414514.html
其实就是加点法:从不属于这个集合的点中找从本集合可以找到的最小边,加入本集合
看代码
#include<iostream> #include<cstdio> #include<cstring> #include<stdio.h> #include<string.h> #include<cmath> #include<math.h> #include<algorithm> #include<set> #include<queue> #include<map> typedef long long ll; using namespace std; const ll mod=1e9+7; const int maxn=1e3+10; const int maxk=100+10; const int maxx=1e4+10; const ll maxe=1000+10; #define INF 0x3f3f3f3f3f3f ll v,e; bool vis[maxn];//顶点i是否在集合X中 ll cost[maxn][maxn];//存两边的权值 ll mincost[maxn];//从集合X出发的边到每个顶点的最小权值 void solve() { ll ans=0; mincost[0]=0; while(true) { int flag=-1; for(int i=0;i<v;i++) { if(!vis[i]&&(flag==-1||mincost[i]<mincost[flag])) flag=i; } if(flag==-1) break; vis[flag]=true; ans+=mincost[flag]; for(int i=0;i<v;i++) { mincost[i]=min(mincost[i],cost[flag][i]); } } cout<<ans<<endl; } int main() { ios::sync_with_stdio(false); cin>>v>>e; for(int i=0;i<v;i++) { for(int j=0;j<v;j++) { cost[i][j]=INF; } mincost[i]=INF; cost[i][i]=0; vis[i]=false; } for(int i=0;i<e;i++) { int a,b,va; cin>>a>>b>>va; cost[a][b]=va; cost[b][a]=va; } solve(); return 0; }
当初的梦想实现了吗,事到如今只好放弃吗~