基准时间限制:1 秒 空间限制:131072 KB 分值: 0
难度:基础题
N个点M条边的无向连通图,每条边有一个权值,求该图的最小生成树。
Input
第1行:2个数N,M中间用空格分隔,N为点的数量,M为边的数量。(2 <= N <= 1000, 1 <= M <= 50000) 第2 - M + 1行:每行3个数S E W,分别表示M条边的2个顶点及权值。(1 <= S, E <= N,1 <= W <= 10000)
Output
输出最小生成树的所有边的权值之和。
Input示例
9 14 1 2 4 2 3 8 3 4 7 4 5 9 5 6 10 6 7 2 7 8 1 8 9 7 2 8 11 3 9 2 7 9 6 3 6 4 4 6 14 1 8 8
Output示例
37
Prime算法
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;
int cost[1020][1020];//cost[u][v]表示边e=(u,v)的权值(不存在的情况下设为INF)
int mincost[1020];//从集合X出发的边到每个顶点的最小权值
bool used[1020];//顶点i是否包含在集合X中
int N,M,S,E,W;
int prime()
{
for(int i=1;i<=N;i++)
{
mincost[i]=INF;
used[i]=false;
}
mincost[1]=0;
int res=0;
while(true)
{
int v=-1;//从不属于X的顶点中选取从X到其权值最小的顶点
for(int u=1;u<=N;u++)
{
if(!used[u]&&(v==-1||mincost[u]<mincost[v]))
v=u;
}
if(v==-1)break;
used[v]=true;//把顶点v加入X
res+=mincost[v];//把边的长度加到结果里
for(int u=1;u<=N;u++)
mincost[u]=min(mincost[u],cost[v][u]);
}
return res;
}
int main()
{
cin>>N>>M;
memset(cost,INF,sizeof(cost));
for(int i=0;i<M;i++)
{
cin>>S>>E>>W;
cost[S][E]=min(W,cost[S][E]);
cost[E][S]=min(W,cost[E][S]);
}
cout<<prime()<<endl;
return 0;
}
Kruskal算法
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;
struct edge{int u,v,cost;};
bool cmp(const edge& e1,const edge& e2){
return e1.cost<e2.cost;
}
edge es[50020];
int V,E;//顶点数和边数
int par[1020];//父亲
int rank[1020];//树的高度
//初始化V个元素
void init()
{
for(int i=0;i<V;i++)
{
par[i]=i;
rank[i]=0;
}
}
//查询树的根
int find(int x)
{
if(par[x]==x)
return x;
return par[x]=find(par[x]);
}
//合并x和y所属的集合
void unite(int x,int y)
{
x=find(x);
y=find(y);
if(x==y)return;
if(rank[x]<rank[y])
par[x]=y;
else
{
par[y]=x;
if(rank[x]==rank[y])
rank[x]++;
}
}
//判断x和y是否属于同一个集合
bool same(int x,int y)
{
return find(x)==find(y);
}
int kruskal()
{
sort(es,es+E,cmp);//按照edge,cost的顺序从大到小
init();//并查集的初始化
int res=0;
for(int i=0;i<E;i++)
{
edge e=es[i];
if(!same(e.u,e.v))
{
unite(e.u,e.v);
res+=e.cost;
}
}
return res;
}
int main()
{
cin>>V>>E;
for(int i=0;i<E;i++)
cin>>es[i].u>>es[i].v>>es[i].cost;
cout<<kruskal()<<endl;
return 0;
}