#P1684. 第5题-小美的人际关系
          
                        
                                    
                      
        
              - 
          
          
                      1000ms
            
          
                      Tried: 347
            Accepted: 63
            Difficulty: 8
            
          
          
          
                       所属公司 : 
                              美团
                                
            
                        
              时间 :2024年3月9日
                              
                      
          
 
- 
                        算法标签>并查集          
 
第5题-小美的人际关系
cpp 代码
#include<iostream>
#include <cstring>
#include <vector>
#include <set>
#include <map>
#include <unordered_map>
#include <queue>
#include <cmath>
#include <list>
#include <functional>
#include <algorithm>
#include <memory>
#include <numeric>
#include <unordered_set>
using namespace std;
typedef pair<int,int> pii;
typedef long long ll;
int a[200010];
int p[200010];
int find(int x){
    if(p[x]!=x){
        p[x] = find(p[x]);
    }
    return p[x];
}
int main(){
    int _t = 1;
//    cin>>_t;
    while(_t--) {
        int n,m,q;cin>>n>>m>>q;
        unordered_map<int,unordered_set<int>> gra;
        unordered_map<int,unordered_set<int>> old_gra;
        int id = 1;
        iota(p+1,p+1+200000,1);
        unordered_map<int,int> map_person;
        for(int i = 1;i<=m;i++){
            int u,v;scanf("%d %d",&u,&v);
            if(!map_person.count(u))map_person[u] = id++;
            if(!map_person.count(v))map_person[v] = id++;
            gra[map_person[u]].insert(map_person[v]);
            gra[map_person[v]].insert(map_person[u]);
            old_gra[map_person[u]].insert(map_person[v]);
            old_gra[map_person[v]].insert(map_person[u]);
        }
        vector<vector<int>> actions;
        for(int i = 1;i<=q;i++){
            int ty,u,v;scanf("%d %d %d",&ty,&u,&v);
            actions.push_back({ty,u,v});
            if(ty==1){
                if(map_person.count(u) && map_person.count(v)) {
                    if (old_gra[map_person[u]].count(map_person[v])) {
                        gra[map_person[u]].erase(map_person[v]);
                        gra[map_person[v]].erase(map_person[u]);
                    }
                }
            }
        }
        for(auto &[u,gu]:gra){
            for(auto &v:gu){
                p[find(u)] = find(v);
            }
        }
        vector<string> res;
        for(int i = actions.size()-1;i>=0;i--){
            int ty = actions[i][0],u = actions[i][1],v = actions[i][2];
            if(ty == 2){
                if(map_person.count(u) && map_person.count(v)){
                    int mu = map_person[u],mv = map_person[v];
                    if(find(mu) == find(mv)){
                        res.push_back("Yes");
                    }
                    else res.push_back("No");
                }else{
                    res.push_back("No");
                }
            }
            else{
                if(map_person.count(u) && map_person.count(v)){
                    int mu = map_person[u],mv = map_person[v];
                    if(old_gra[mu].count(mv)){
                        p[find(mu)] = find(mv);
                    }
                }
            }
        }
        for(int i = res.size()-1;i>=0;i--){
            cout<<res[i]<<endl;
        }
    }
    return 0;
}
//1 2
//2 3
//4 5
//1 1 5
//2 1 3
//2 1 4
//1 1 2
//2 1 3
java
#include<bits/stdc++.h>
using namespace std;
int w[4];
unordered_set<int>st;
unordered_map<int,int>mp{{2,5},{5,2},{6,9},{9,6}};
vector<int>res;
bool vis[4];
void dfs(int u,int sum,int len){
    if(u==len){
        res.push_back(sum);
    }
    for(int i=0;i<4;i++){
        if(vis[i])continue;
        int x=w[i];
        vis[i]=true;
        dfs(u+1,sum*10+x,len);
        if(mp.count(x)){
            dfs(u+1,sum*10+mp[x],len);
        }
        vis[i]=false;
    }
}
int main(){
    for(int i=0;i<4;i++){
        scanf("%d,",&w[i]);
        st.insert(w[i]);
    }
    sort(w,w+4);
    int n=w[3];
    if(st.count(2)&&st.count(5)||st.count(6)&&st.count(9)||st.count(0)){
        puts("-1");
    }
    else{
        for(int len=1;len<=4;len++){
            dfs(0,0,len);
        }
        set<int>s(res.begin(),res.end());
        res.assign(s.begin(),s.end());
        int m=res.size();
        if(n<m)cout<<res[n-1]<<endl;
        else cout<<res.back()<<endl;
    }
    return 0;
}
python
n,m,q = map(int, input().split())
fa = {}
def find(x):
    if x == fa[x]: return x
    fa[x] = find(fa[x])
    return fa[x]
def union(x,y):
    if u not in fa: fa[u] = u
    if v not in fa: fa[v] = v
    fa[find(x)] = find(y)
edges = set()
for _ in range(m):
    u,v = map(int, input().split())
    if u not in fa: fa[u] = u
    if v not in fa: fa[v] = v
    edges.add((u,v))
ops = []
del_edges = set()
for _ in range(q):
    op,u,v = map(int, input().split())
    ops.append([op,u,v])
    if op == 1:
        if (u,v) in edges:
            del_edges.add((u,v))
        if (v,u) in edges:
            del_edges.add((v,u))
# 逆向构图
for u,v in edges:
    if (u,v) in del_edges or (v,u) in del_edges:
        # 要删除的边
        continue
    union(u,v)
ans = []
#逆向遍历
for i in range(q-1,-1,-1):
    op,u,v = ops[i]
    if op == 2:
        if u in fa and v in fa and find(u) == find(v):
            ans.append("Yes")
        else:
            ans.append("No")
    else:
        union(u,v)
ans.reverse()
for a in ans:
    print(a)
        题目描述
小美认为,在人际交往中,但是随着时间的流逝,朋友的关系也是会慢变淡的,最终朋友关系就淡忘了 现在初始有一些朋友关系,存在一些事件会导致两个人淡忘了他们的朋友关系。小美想知道某一时刻中,某两人是否可以通过朋友介绍互相认识?
事件共有2种: 1u v:代表编号u的人和编号v的人淡忘了他们的朋友关系。 2 u v:代表小美查询编号u的人和编号v的人是否能通过朋友介绍互相认识. 注:介绍可以有多层,比如2号把1号介绍给3号,然后3号再把1号介绍给4号,这样1号和 4 号就认识了。
输入描述
第一行输入三个正整数n,m,q,代表总人数,初始的朋友关系数量,发生的事件数量
接下来的m行,每行输入两个正整数u,v、,代表切始编号u的人和编号v的人是朋友关系
接下来的q行,每行输入三个正整数op,u,v,含义如题目描述所述,
1≤n≤109
1≤m,q≤105
1≤u,v≤n
1≤op≤2
输出描述
对于每次2号操作,输出一行字符用代表查询的答案。
如果编号u的人和编号v的人能通过朋友介绍互相认识,则输出"Yes"。否则输出"No"
样例
输入
5 3 5
1 2
2 3
4 5
1 1 5
2 1 3
2 1 4
1 1 2
2 1 3
输出
Yes
No
No