您的位置:首页 > 其它

MST中求任意两点条路径上的最长边…

2013-12-14 20:06 267 查看
1、MST任意两点路径上的最长边

   这其实是在求次小生成树 , 因为我们可以知道 ,
次小生成树和最小生成树之间只有一条边不一样 , 因此我们只需要枚举不在最小生成树中边 ,
同时我也要求出该两点在最小生成树中之间的路径中的最长边的值。

解法:我们用kruskal算法来求出最小生成树 , 对于kruskal算法 , 当我们要加入一条边时 , 实际上是在把两颗“树”合并
, 那么从这两颗树上各去除一个点 , 则这两点路径之间的最大边 , 就是当前加入的这条边,因此我们只需要记录每颗树就行了 ,
对于每颗树我们可以用邻接表(数组模拟)来存 。

代码:

int kruskal()

{

    sort(edge ,
edge+m , cmp); //对边进行排序

    int i , x ,
y , g , h , k = 0;

    int sum =
0;

    for(i = 0; i
< n; i++) //先把每个点都看成是一颗树

    {

   
    link[i].x =
i+1;

   
    link[i].next
= head[i+1];

   
    end[i+1] =
i;

   
    head[i+1] =
i;

    }

    for(i = 0; ;
i++)

    {

   
    if(k ==
n-1)  break;

   
    x =
find(edge[i].x); // 判断这两个点是不是在同一颗树上

   
    y =
find(edge[i].y);

   
    if(x !=
y)

   
    {

   
   

   
   
    for(int w =
head[x]; w != -1 ; w = link[w].next)

   
   
    {

   
   
   
    for(int v =
head[y]; v != -1; v = link[v].next)

   
   
   
    {

   
   
   
   
   
length[link[w].x][link[v].x] = length[link[v].x][link[w].x] =
edge[i].w;

   
   
   
    }

   
   
    }

   
   
   
link[end[x]].next = head[y];//两个树合并成一颗树

   
   
    end[x] =
end[y];

   
   
    p[y] = x;
//这是并查集的合并 , 但要和上面的合并相对应

   
   
    k++;

   
   
   

   
   
    sum +=
edge[i].w;

   
    }

    }

    return
sum;

}

2、MST中任意两点路径上的最短边

解法:这和上面的解法差不多 。 也和上面一样 , 用kruskal算法 , 当成是两颗树的合并 。 我假设现在要加入u 、 v这条边
, 并且保证u 、 v不在同一颗树上 , 那么假设点 x 在u 的树上 、 点y在 v的树上 , 
现在我们要求x 、y路径上的最小边 , 如果x就u , y就是v , 那么它们之间的最短边就是u、v之间的权值 , 如果x不是u ,
y不是v , 那么就意味着在x、y的路径上 , 除了u、v这条边之外 , 还有其他的边 ,
并且我们知道这条其他的边的权值肯定要比u、v之间的权值小 , 因此x、y之间的最短边 = min(u到x之间最短边 ,
v到y之间最短边)。

代码:

int kruskal()

{

    sort(edge ,
edge+m , cmp); //对边进行排序

    int i , x ,
y , g , h , k = 0;

    int sum =
0;

    for(i = 0; i
< n; i++)

    {

   
    link[i].x =
i+1;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: