最小生成树
算法一:prime
特别好用的 O(n^2)和dij 差了两行
#include<bits/stdc++.h> using namespace std; #define LOACL freopen("in","r",stdin);\ freopen("out","w",stdout); #define add(u,v,w) (e[++tot]=(edge){v,head[u],1},head[u]=tot;) #define f(i,l,r) for(int i=l;i<=r;++i) #define g(i,l,r) for(int i=l;i>=r;--i) #define CLR(arr,val) memset(arr,val,sizeof(arr)) typedef long long ll; const int sz = (int)1e4+6; const int inf =0x3f3f3f; int n,sum; int g[sz][sz],dis[sz],vis[sz]; void prim() { f(i,1,n)dis[i]=g[1][i]; vis[1]=1; // int ans= 0; f(i,1,n-1) { int mm = inf ,pos; f(j,1,n) { if(!vis[j]&& dis[j]< mm) { mm =dis[j]; pos =j; } } if(mm==inf)break; vis[pos]=1; f(j,1,n) { if(!vis[j] && dis[j]>g[pos][j]) { dis[j]=g[pos][j]; } } } } int main() { LOACL CLR(dis,inf); CLR(vis,0); cin>>n; f(i,1,n)f(j,1,n)cin>>g[i][j]; prim(); f(i,1,n)sum+=dis[i]; cout<<sum<<endl; return 0; }
算法二:krsucal
适用范围: 稀疏图
原理:查并集+贪心 巨简单好写
#include<bits/stdc++.h> using namespace std; #define LOACL freopen("in","r",stdin);\ freopen("out","w",stdout); #define add(u,v,w) (e[++tot]=(edge){v,head[u],1},head[u]=tot;) #define f(i,l,r) for(int i=l;i<=r;++i) #define g(i,l,r) for(int i=l;i>=r;--i) #define CLR(arr,val) memset(arr,val,sizeof(arr)) typedef long long ll; const int sz =1e6+5; int n,m ; struct node { int u,v,w; }no[sz]; bool cmp(node l,node r) { return l.w<r.w; } int fa[sz]; int getf(int x) { if(x!=fa[x]) fa[x] =getf(fa[x]); return fa[x]; } void uni(int x,int y) { int fx = getf(x); int fy = getf(y); if(fx!=fy)fa[fx]=fy; } int krusal() { int ans=0; f(t,1,m) if(getf(no[t].u) != getf ( no[t].v)) { uni(no[t].u,no[t].v); ans+=no[t].w ; } return ans; } int main() { LOACL cin>>n>>m; f(i,1,m) cin>>no[i].u>>no[i].v>>no[i].w; sort(no+1,no+m+1,cmp); f(i,1,n)fa[i]=i; printf("%d",krusal()); return 0; }
算法三: 堆优化prime
适用范围:稀疏图
顺便写一下stl堆操作
#include<bits/stdc++.h> using namespace std; #define LOACL freopen("in","r",stdin);\ freopen("out","w",stdout); const int inf = 987654321; const int sz = 1e6 + 5; const int mod = 1e9 + 7; const int sqrtn = 300; #define add(u,v,w) (e[++tot]=(edge){v,head[u],1},head[u]=tot;) #define f(i,l,r) for(int i=l;i<=r;++i) #define g(i,l,r) for(int i=l;i>=r;--i) #define CLR(arr,val) memset(arr,val,sizeof(arr)) typedef long long ll; int main() { LOACL int arr[]={123,45,15,151,351,23145,343,} ; vector<int> v; f(i,0,sizeof(arr)/sizeof(arr[0])-1) v.push_back(arr[i]); make_heap(v.begin(),v.end()); cout<<v.front()<<endl; pop_heap(v.begin(),v.end()); v.pop_back(); v.push_back(4444444); push_heap(v.begin(),v.end()); cout<<v.front()<<endl; sort_heap (v.begin(),v.end()); cout<<v.front()<<endl; sort_heap (v.begin(),v.end()); cout<<v.front()<<endl; return 0; }
#include<bits/stdc++.h> using namespace std; #define LOACL freopen("in","r",stdin);\ freopen("out","w",stdout); const int inf = 987654321; const int sz = 1e6 + 5; const int mod = 1e9 + 7; const int sqrtn = 300; #define add(u,v,w) (e[++tot]=(edge){v,head[u],1},head[u]=tot;) #define f(i,l,r) for(int i=l;i<=r;++i) #define g(i,l,r) for(int i=l;i>=r;--i) #define CLR(arr,val) memset(arr,val,sizeof(arr)) typedef long long ll; struct node { int u,v,w; bool operator < (const struct node & n)const { return w > n.w; } }; vector<node> heap; vector<node>g[sz]; bool vis[sz]; int n,m,u,v,w; void push(node & n) { heap.push_back(n); push_heap(heap.begin(),heap.end()); } void pop() { pop_heap(heap.begin(),heap.end()); heap.pop_back(); } int main() { LOACL cin>>n>>m; f(i,1,m) { cin>>u>>v>>w; g[u].push_back((node){u,v,w}); g[v].push_back((node){v,u,w}); } vis[1]=1; f(i,0,g[1].size()-1) { push(g[1][i]); } int all=0; int cnt= 0; while(cnt<n-1) { int w= heap[0].w; int v = heap[0].v; pop(); if(vis[v])continue; vis[v]=true; all+=w; cnt++; f(i,0,g[v].size()-1) { if(!vis[g[v][i].v]) push(g[v][i]); } } cout<<all<<endl; return 0; }
不摸着石头过河,难道要在温柔乡睡到天昏地暗。

浙公网安备 33010602011771号