最小生成树模板
Kruskal
思想:贪心+并查集
#include <bits/stdc++.h>
using namespace std;
const int N=5e3+10;
const int M=2e5+10;
typedef long long ll;
int n,m;
struct edge
{
int x,y,z;
}edges[M];
int father[N];
void init()
{
for(int i=0;i<n;i++)father[i]=i;
}
int find(int x)
{
return x==father[x]?x:father[x]=find(father[x]);
}
bool join(int x,int y)
{
int fx = find(x);
int fy = find(y);
if(fx!=fy)
{
father[fx]=fy;
return true;
}
else return false;
}
bool cmp(edge a,edge b)
{
return a.z<b.z;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n>>m;
init();
for(int i=0;i<m;i++)
{
cin>>edges[i].x>>edges[i].y>>edges[i].z;
}
sort(edges,edges+m,cmp);
// for(int i=0;i<m;i++)
// {
// cout<<edges[i].x<<' '<<edges[i].y<<' '<<edges[i].z<<endl;
// }
int ans=0;
int cnt=0;
for(int i=0;i<m;i++)
{
if(join(edges[i].x,edges[i].y))
{
cnt++;
ans+=edges[i].z;
}
}
if(cnt!=n-1)cout<<"orz"<<endl;
else cout<<ans<<endl;
return 0;
}
Prim
#include <bits/stdc++.h>
using namespace std;
const int N=5e3+10;
typedef long long ll;
int n,m;
bool vis[N];
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n>>m;
memset(vis,false,sizeof(vis));
vector<vector<pair<int,int>>>edges(n+1);
for(int i=0;i<m;i++)
{
int u,v,w;
cin>>u>>v>>w;
edges[u].push_back(make_pair(v,w));
edges[v].push_back(make_pair(u,w));
}
priority_queue<pair<int,int>,vector<pair<int,int>>,greater<pair<int,int>>>heap;
vis[1]=true;
ll ans=0;
int cnt=1;
for(auto edge : edges[1])
{
heap.push({edge.second,edge.first});
}
while(!heap.empty())
{
int cost = heap.top().first;
int node = heap.top().second;
heap.pop();
if(vis[node])continue;
ans+=cost;
vis[node]=true;
cnt++;
for(auto edge:edges[node])
{
int w = edge.second;
int next = edge.first;
if(!vis[next])heap.push({w,next});
}
}
if(cnt!=n)cout<<"orz"<<endl;
else cout<<ans<<endl;
return 0;
}
Prim算法优化版
时间复杂度O(n + m) + O((m+n) * log n)
#include <bits/stdc++.h>
using namespace std;
const int N=5e3+10;
const int M=4e5+10;
typedef long long ll;
int n,m;
int head[N];
int nt[M];
int to[M];
int heap[N][2];
int where[N];
int weight[M];
int cnt=0;
int cnt2=1;
int hsz=0;
int u,v,w;
void addEdge(int u,int v,int w)
{
nt[cnt2] = head[u];
to[cnt2] = v;
weight[cnt2]=w;
head[u]=cnt2++;
}
bool isEmpty()
{
return hsz==0;
}
void heapInsert(int i)
{
while(heap[i][1]<heap[(i-1)/2][1])
{
swap(heap[i],heap[(i-1)/2]);
swap(where[heap[i][0]],where[heap[(i-1)/2][0]]);
i = (i-1)/2;
}
}
void update(int i)
{
int v = to[i];
int w = weight[i];
if(where[v]==-1)
{
heap[hsz][0]=v;
heap[hsz][1]=w;
where[v] = hsz++;
heapInsert(where[v]);
}
else if(where[v]>=0)
{
heap[where[v]][1]=min(heap[where[v]][1],w);
heapInsert(where[v]);
}
}
void heapify(int i)
{
int l=i*2+1;
while(l<hsz)
{
int best = l+1 < hsz && heap[l+1][1]<heap[l][1] ? l+1:l;
best = heap[best][1] < heap[i][1] ? best : i;
if(best == i)
{
break;
}
swap(heap[best],heap[i]);
swap(where[heap[best][0]],where[heap[i][0]]);
i = best;
l = i * 2 + 1;
}
}
void pop()
{
u = heap[0][0];
w = heap[0][1];
swap(heap[0],heap[--hsz]);
swap(where[heap[0][0]],where[heap[hsz][0]]);
heapify(0);
where[u]=-2;
cnt++;
}
int prim()
{
cnt=1;
where[1]=-2;
for(int i=head[1];i>0;i=nt[i])
{
update(i);
}
int ans=0;
while(!isEmpty())
{
pop();
ans+=w;
for(int i=head[u];i>0;i=nt[i])
{
update(i);
}
}
return ans;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n>>m;
memset(where,-1,sizeof(where));
for(int i=1;i<=m;i++)
{
cin>>u>>v>>w;
addEdge(u,v,w);
addEdge(v,u,w);
}
int ans = prim();
if(cnt==n)cout<<ans<<endl;
else cout<<"orz"<<endl;
return 0;
}

浙公网安备 33010602011771号