小美的朋友关系

小美认为,在人际交往中,但是随着时间的流逝,朋友的关系也是会慢慢变淡的,最终朋友关系就淡忘了。
现在初始有一些朋友关系,存在一些事件会导致两个人淡忘了他们的朋友关系。小美想知道某一时刻中,某两人是否可以通过朋友介绍互相认识?
事件共有 2 种:
1 u v:代表编号 u 的人和编号 v 的人淡忘了他们的朋友关系。
2 u v:代表小美查询编号 u 的人和编号 v 的人是否能通过朋友介绍互相认识。

#include <iostream>
#include <unordered_map>
#include <unordered_set>
#include <stack>
#include <set>
using namespace std;

unordered_map<int, int> parents;

struct operation {
    bool op;
    int u, v;
};

inline int find(int x);
inline void uni(int x, int y);

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n, m, q;
    cin >> n >> m >> q;

    set<pair<int, int>> record, rm;
    for (int i = 0; i < m; ++i) {
        int u, v;
        cin >> u >> v;
        if(v>u) swap(u,v);
        if (parents.find(u) == parents.end()) {
            parents[u] = u;
        }
        if (parents.find(v) == parents.end()) {
            parents[v] = v;
        }
        record.emplace(u, v);
    }

    stack<operation> st;
    for (int i = 0; i < q; ++i) {
        int op, u, v;
        cin >> op >> u >> v;
        if(v>u)swap(u,v);
        if (parents.find(u) == parents.end()) {
            parents[u] = u;
        }
        if (parents.find(v) == parents.end()) {
            parents[v] = v;
        }
        bool opt=(op==1);
        operation o{opt, u, v};
        st.emplace(o);
        if (opt) {
            auto m = pair<int, int>(u, v);
            if (record.find(m) != record.end()) {
                record.erase(m);
                rm.emplace(m);
            }
        }
    }

    for (const auto& s : record) {
        uni(s.first, s.second);
    }

    stack<bool> answers;
    while (!st.empty()) {
        operation o = st.top();
        st.pop();
        int u = o.u, v = o.v;
        bool opt=o.op;
        if (opt) {
            auto m = pair<int, int>(u, v);
            if (rm.find(m) != rm.end()) {
                uni(u, v);
            }
        } else {
            answers.emplace(find(u) == find(v));
        }
    }

    while (!answers.empty()) {
        cout << (answers.top() ? "Yes" : "No") << endl;
        answers.pop();
    }

    return 0;
}

inline int find(int x) {
    if (parents[x] != x) {
        parents[x] = find(parents[x]);
    }
    return parents[x];
}

inline void uni(int x, int y) {
    int rootX = find(x);
    int rootY = find(y);
    parents[rootY]=rootX;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值