100个小问题_每日一题_第4题

problem4:连通性问题 

   假如已知一个整数对序列,其中每个整数代表某种类型的一个对象,而且将p-q对解释成"p与q连通"。假定连通关系是可传递的,即:如果p与q连通,同时q与r连通,则p与r也连通。 
   任务:编写一个程序,从一个整数对结合中过滤额外的链接对。即当程序输入一个整数对p-q,仅当程序此时已经看到的对不能通过可传递性证明p与q连通时,它才输出该对。如果前面的对表明p与q连通,则程序应该忽略p-q,并且继续输入下一个对。 
样列输入: 
3 4 
4 9 
8 0 
2 3 
5 6 
2 9 
5 9 
7 3 
4 8 
5 6 
0 2 
6 1 
样列输出: 
3 4 
4 9 
8 0 
2 3 
5 6 
5 9 
7 3 
4 8 
6 1 

 

 

      恩,大家回答得都比较对,这个题目的最好解答就是用并集查找,ysg同学的算法实现了直接的并集查找但是对于有N个对象何M个对的连通性问题,ysg同学的算法时间复杂度为O(M*N)。而事实上,正如他所说在实现时,可以通过开辟一个数组来保存每颗树的节点数,在连通时,总是连通较小的树连接到较大树,这样可以保证在判断N个对象的其中两个对象是否连通时,最多需要跟踪2lgN个节点,最后的优化的就是进行路径压缩。 

      以下是paoblem4的一个比较好的实现,在路径压缩时使用的是对分路径压缩。具体过程请大家自己分析一下语句,顺便分析一下算法的性能,并且思考如何产生一组输入序列使下面程序生成一条长度为5的搜索路径. 

#include <stdio.h> 
#define MAX_N  10000 

int main() { 
    int i, j, p, q; 
    int id[MAX_N], sz[MAX_N]; 
    for (i = 0; i < MAX_N; ++i) { 
        id[i] = i; 
        sz[i] = 1; 
    } 
    while (scanf("%d %d", &p, &q) == 2) { 
        for (i = p; i != id[i]; i = id[i]) 
            id[i] = id[id[i]]; 
        for (j = q; j != id[j]; j = id[j]) 
            id[j] = id[id[j]]; 
        if (i == j) continue; 
        if (sz[i] < sz[j]) { 
            id[i] = j; 
            sz[j] += sz[i]; 
        } else { 
            id[j] = i; 
            sz[i] += sz[j]; 
        } 
        printf("%d/t%d/n", p, q); 
    } 
    return 0; 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值