day54-graph theory-part05-8.25

tasks for today:

1. 并查集理论基础

2. 寻找存在的路径

----------------------------------------------------------------

1. 并查集理论基础

并查集主要有三个功能:

  1. 寻找根节点,函数:find(int u),也就是判断这个节点的祖先节点是哪个
  2. 将两个节点接入到同一个集合,函数:join(int u, int v),将两个节点连在同一个根节点上
  3. 判断两个节点是否在同一个集合,函数:isSame(int u, int v),就是判断两个节点是不是同一个根节点
int n = 1005; // n根据题目中节点数量而定,一般比节点数量大一点就好
vector<int> father = vector<int> (n, 0); // C++里的一种数组结构

// 并查集初始化
void init() {
    for (int i = 0; i < n; ++i) {
        father[i] = i;
    }
}
// 并查集里寻根的过程
int find(int u) {
    return u == father[u] ? u : father[u] = find(father[u]); // 路径压缩
}

// or using this more explicit one

int find(int u) {
    if u == father[u]: return u
    else: return father[u] = find(father[u])
}

// 判断 u 和 v是否找到同一个根
bool isSame(int u, int v) {
    u = find(u);
    v = find(v);
    return u == v;
}

// 将v->u 这条边加入并查集
void join(int u, int v) {
    u = find(u); // 寻找u的根
    v = find(v); // 寻找v的根
    if (u == v) return ; // 如果发现根相同,则说明在一个集合,不用两个节点相连直接返回
    father[v] = u;
}

2. 寻找存在的路径

please note, in this practice, the graph is a non-directed graph, so as long as there is an edge between two points, they can be connected to a same root, which equals to the operation of "join", then finding if there is way between two points means if they have same roots, so "isSame" can be used to judge if there is a way between them.

def find(u, father):
    if u == father[u]: 
        return u
    else: 
        return find(father[u], father)
def join(u, v, father):
    u = find(u, father)
    v = find(v, father)
    if u == v: return
    father[v] = u

def isSame(u, v, father):
    u = find(u, father)
    v = find(v, father)
    return u == v

def main():
    n, m = map(int, input().split())
    father = list(range(0, 100))
    
    for _ in range(m):
        s, t = map(int, input().split())
        join(s, t, father)
        
    start, end = map(int, input().split())
    
    
    if isSame(start, end, father): 
        print(1)
    else: 
        print(0)

    
if __name__ == "__main__":
    main()
        
  • 13
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值