最小生成树模版(Kruskal)
最近研究了这东西 感觉十分有用 在对于少边的情况下效果十分明显
本程序使用优先队列存储边信息 使用并查集判定是否已经连通 O(eloge)的复杂度
#include <iostream>
#include <queue>
using namespace std;
const long MAXN=10000;
long hash[MAXN];
long m,n;//点数 边数
//m标号从1开始
typedef struct
{
long from;
long to;
long cost;
}Edge;
bool operator <(const Edge &a, const Edge &b)
{
return a.cost>b.cost;
}
priority_queue<Edge> q;
Edge e;
void MakeSet()
{
long i;
for (i=0;i<=m;++i)
{
hash[i]=i;
}
}
long Find(long i)
{
long r=i;
while (hash[r]!=r)
{
r=hash[r];
}
while (hash[i]!=r)
{
long j=hash[i];
hash[i]=r;
i=j;
}
return r;
}
void Unition(long x,long y)
{
long fx=Find(x);
long fy=Find(y);
if (fx!=fy)
{
hash[fx]=fy;
}
}
void Init()
{
while (!q.empty())
{
q.pop();
}
MakeSet();
long i;
for(i=0;i<n;++i)
{
scanf("%ld %ld %ld",&(e.from),&(e.to),&(e.cost));//得到源点 终点
q.push(e);
//以下为无向图的处理
swap(e.from,e.to);
q.push(e);
}
}
void print(long cost)
{
printf("%ld\n",cost);
}
void Kruskal()
{
Init();
long t=0;//表示合并次数
long cost=0;
Edge e;
while (!q.empty()&&t<m-1)
{
e=q.top();
long v1=e.from;
long v2=e.to;
if (Find(v1)!=Find(v2))
{
Unition(v1,v2);
cost+=e.cost;
++t;
}
q.pop();
}
print(cost);
}
int main()
{
while(scanf("%ld %ld",&m,&n)!=EOF)//输入点与边
{
Kruskal();
}
return 0;
}




浙公网安备 33010602011771号