次小生成树的Kruskal实现

    通常次小生成树是使用Prim算法进行实现的,因为可以在Prim算法松弛的同时求得最小生成树上任意两点之间的最长边。但是利用Kruskal算法却没办法在松弛的同时求得。

    所以我们就要在Kruskal求完最短路后,对于每个顶点bfs一次,得到树上任意两点的最长边。之后求可以像之前一样枚举不在树上的边,代替找最小值了。

    两种方法的时间杂度是一样的,但Kruskal的实现代码回长非常多,不过Kruskal的实现可以处理Prim难以处理的重边。


代码实现以Uva 10462为例:

#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
#define INF 0x3f3f3f3f
#define fi first
#define se second
#define mem(a,b) memset((a),(b),sizeof(a))

const int MAXV=100+3;
const int MAXE=200+3;

struct Edge
{
    int from,to,cost;
    Edge(int f=0,int t=0,int c=0):from(f),to(t),cost(c){}
    bool operator<(const Edge &other)const
    {
        return cost > G[MAXV];//最小生成树

void init()//初始化
{
    for(int i=1;i<=E;++i)
        used[i]=false;
    for(int i=1;i<=V;++i)
    {
        par[i]=i;
        high[i]=0;
        G[i].clear();
    }
}

int findfather(int x)
{
    return par[x]=par[x]==x?x:findfather(par[x]);
}

bool unite(int a,int b)
{
    int fa=findfather(a),fb=findfather(b);
    if(fa==fb)
        return false;
    if(high[fa]>high[fb])
        par[fb]=fa;
    else
    {
        par[fa]=fb;
        if(high[fa]==high[fb])
            ++high[fb];
    }
    return true;
}

void bfs(int s)
{
    mem(vis,0);
    vis[s]=true;
    the_max[s][s]=0;
    queue que;
    que.push(s);
    while(!que.empty())
    {
        int u=que.front(); que.pop();
        for(int i=0;i

你可能感兴趣的:(算法,图论)