问题 A: 第一题

部署运行你感兴趣的模型镜像

题目描述
该题的目的是要你统计图的连通分支数。

输入
每个输入文件包含若干行,每行两个整数i,j,表示节点i和j之间存在一条边。

输出
输出每个图的联通分支数。

样例输入

1 4
4 3
5 5

样例输出

2

思路一:利用并查集,连通分支数相当于集合数量。

#include <cstdio>
#include <unordered_set>
using namespace std;

const int maxn = 200010;
int father[maxn]; //存放父亲结点
unordered_set<int> st;

//初始化
void init() {
    for (int i = 1; i <= maxn; i++) {
        father[i] = i;
    }
}

// findFather函数返回元素x所在集合的根结点
int findFather(int x) {
    int a = x;
    while (x != father[x]) {
        x = father[x];
    }
    //路径压缩(可不写)
    while (a != father[a]) {
        int z = a;
        a = father[a];
        father[z] = x;
    }
    return x;
}

//合并a和b所在集合
void Union(int a, int b) {
    int fA = findFather(a);
    int fB = findFather(b);
    if (fA != fB) {
        father[fA] = fB;
    }
}

int main() {
    int a, b;
    init();
    while (scanf("%d%d", &a, &b) != EOF) {
        Union(a, b);
        st.insert(a);
        st.insert(b);
    }
    int ans = 0; //集合数量
    for (auto it = st.begin(); it != st.end(); it++) {
        if (father[*it] == *it) ans++; //根结点
    }
    printf("%d", ans);
    return 0;
}

思路二:基于邻接表的深度优先遍历。

#include <cstdio>
#include <vector>
#include <unordered_set>
using namespace std;

const int maxn = 200010;
vector<int> Adj[maxn];
unordered_set<int> st;
bool vis[maxn] = {0};

void DFS(int u) {
    vis[u] = true;
    for (int i = 0; i < Adj[u].size(); i++) {
        if (!vis[Adj[u][i]]) {
            DFS(Adj[u][i]);
        }
    }
}

void DFSTrave() {
    int sum = 0;
    for (auto it = st.begin(); it != st.end(); it++) {
        if (!vis[*it]) {
            DFS(*it);
            sum++;
        }
    }
    printf("%d", sum);
}

int main() {
    int a, b;
    while (scanf("%d%d", &a, &b) != EOF) {
        Adj[a].push_back(b);
        Adj[b].push_back(a);
        st.insert(a);
        st.insert(b);
    }
    DFSTrave();
    return 0;
}

您可能感兴趣的与本文相关的镜像

ACE-Step

ACE-Step

音乐合成
ACE-Step

ACE-Step是由中国团队阶跃星辰(StepFun)与ACE Studio联手打造的开源音乐生成模型。 它拥有3.5B参数量,支持快速高质量生成、强可控性和易于拓展的特点。 最厉害的是,它可以生成多种语言的歌曲,包括但不限于中文、英文、日文等19种语言

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值