一、最小生成树
1、prim() 算法
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=1e4+5,inf=0x3f3f3f3f;
int dist[N],vis[N],map[N][N];
int n,m;//m表示有m条道;
int sum;
void prepare()
{
for(int i=1; i<=n; i++)
for(int j=1; j<=n; j++)
if(i==j)
map[i][j]=0;
else
map[i][j]=inf;
}
void prim()
{
memset(vis,0,sizeof(vis));
for(int i=1; i<=n; i++)
dist[i]=map[1][i];
vis[1]=1;
for(int i=1; i<n; i++)
{
int minn=inf,k;
for(int j=1; j<=n; j++)
if(!vis[j]&&dist[j]<minn)
minn=dist[j],k=j;
vis[k]=1;
sum+=minn;
for(int j=1; j<=n; j++)
if(!vis[j]&&dist[j]>map[k][j])
dist[j]=map[k][j];
}
}
int main()
{
cin>>n>>m;
prepare();
for(int i=0; i<m; i++)
{
int a,b,c;
cin>>a>>b>>c;
map[a][b]=map[b][a]=min(map[a][b],c);
}
sum=0;
prim();
if(sum==inf)
cout<<"orz"<<endl;//说明不能形成最小生成树
else
cout<<sum<<endl;
return 0;
}
2、kruskal() 算法
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=5e5+5,inf=0x3f3f3f3f;
int n,m;
int pre[N];
struct edge
{
int from,to,w;
} e[N];
bool cmp(edge a,edge b)
{
return a.w<b.w;
}
int find(int x)
{
return pre[x]==x?x:pre[x]=find(pre[x]);
}
int kruskal()
{
for(int i=1; i<=n; i++)
pre[i]=i;
sort(e,e+m,cmp);
int ans=0,res=0;
for(int i=0; i<m; i++)
{
int u=e[i].from,v=e[i].to,w=e[i].w;
u=find(u),v=find(v);
if(u==v)
continue;
else
pre[u]=v,res++,ans+=w;
}
if(res<n-1)//不能形成最小生成树
ans=inf;
return ans;
}
int main()
{
cin>>n>>m;
for(int i=0; i<m; i++)
cin>>e[i].from>>e[i].to>>e[i].w;
int ans=kruskal();
if(ans==inf)
cout<<"orz"<<endl;
else
cout<<ans<<endl;
return 0;
}