您的位置:首页 > 其它

uva 11354 Bond

2013-12-14 20:03 295 查看
这题要求最小瓶颈路 , 由于数据太多 , 所以用一般的bfs或dfs肯定会超时 。

在这个题目上就应该充分的考虑到 , 最小生成树是一棵树 , 所有就可以通过树的性质来解决这个问题 。

1、首先把最小生成树 , 建成一颗有根树 , 最好用bfs因为dfs可能会爆栈。

2、在建树的时候 ,
记录每个点的深度(根节点的深度为0)、每个节点的父亲节点(根节点的为-1)、每个节点和父亲节点的距离(根节点为0);

3、然后再通过题目给出的两个节点 ,  来遍历这颗树 。

4、如果这两个节点的深度不一样 , 那么就先要把深度调成一样 ,

5、深度一样之后 , 再同时往树根的方向遍历 , 则在这个遍历过程 , 一定会得到两个节点的祖先是一样的 ,
到了这个时候就得到了我们想要的结果。

时间复杂度分析:这个算法之所以快 , 是因为我们两个节点同时在走 , 就等于是双向搜索一样 , 并且大多数情况下 ,
都不需要遍历所有的节点。

代码:

#include

#include

#include

#include

#include

#include

#include

using namespace std;

struct node

{

    int from ,
to ;

    int
dist;

    node(int
from , int to , double dist)

    {

   
   
this->from = from;

   
    this->to
= to;

   
   
this->dist = dist;

    }

    bool
operator <(const struct node &ans) const

    {

   
    return dist
> ans.dist;

    }

};  // 这是为了用优先队列来存储所有边

const int MAXN = 50000+5 ;

int n , m  , p[MAXN] , f[MAXN]; 
//  记录父亲节点 、 深度

int dist[MAXN];  // 
记录节点和父亲节点的距离

priority_queueedge;

void init()

{

    int i , x ,
y , z;

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

   
    f[i] =
i;

    for(i = 1; i
<= m; i++)

    {

   
    scanf("%d %d
%d" , &x , &y  , &z);

   
   
edge.push(node(x , y , z));

    }

    memset(dist
, 0 , sizeof(dist));

    memset(p , 0
, sizeof(p));

}

int find(int x)  //并查集 ,
来判断新加入的两个节点是否属于同一个连通图

{

    int y =
x;

    while(x !=
f[x])

   
    x =
f[x];

    while(y !=
x)

    {

   
    int xy =
f[y];

   
    f[y] =
x;

   
    y =xy;

    }

    return
x;

}

void mintree()  //  求最小生成树 ,
并将其转变为有根树

{

    int bz
=0  , done[MAXN];

   
vectords[MAXN];

   
vectorq[MAXN];

   
while(!edge.empty())

    {

   
    struct node
s = edge.top();

   
   
edge.pop();

   
    int x =
find(s.from) , y = find(s.to);

   
    if(x !=
y)

   
    {

   
   
    f[y] =
x;

   
   
    bz +=
1;

   
   
   
q[s.from].push_back(s.to); //用邻接表来记录最小生成树的边 , 并记录所加入边的权 ,
并使其相对应

   
   
   
q[s.to].push_back(s.from);

   
   
   
ds[s.to].push_back(s.dist);

   
   
   
ds[s.from].push_back(s.dist);

   
    }

   
    if(bz ==
n-1)  break; 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: