基准时间限制: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; }