E. Graph Composition

 avatar
unknown
c_cpp
14 days ago
2.7 kB
5
Indexable
#include <iostream>
#include <ranges>
#include <algorithm>
#include <vector>
#include <unordered_map>
#include <unordered_set>
#include <ranges>

using namespace std;


void findConnected(vector<vector<int>>& graph, vector<vector<int>>& connectedComps, vector<int>& NodeConnectedIdx) {
  int connectedId = 0;
  vector<bool> visited(graph.size()+1);

  auto dfs = [&](this auto const& dfs, int vertex, int connectedId) -> void {
    visited[vertex] = true;
    connectedComps[connectedId].push_back(vertex);
    NodeConnectedIdx[vertex] = connectedId;
    for(auto adjacentNode : graph[vertex]){
      if(visited[adjacentNode]){continue;}
      dfs(adjacentNode, connectedId);
    }
  };

  for(int i = 1; i < graph.size(); i++){
    if(!visited[i]){
      connectedComps.push_back({});
      dfs(i, connectedId++);
    }
  }
}

int removeExtraEdges(vector<vector<int>>& F, vector<vector<int>>& connectedG, vector<int>& nodeConnectedIdx){
  int numSteps{};
  for(int vertex = 1; vertex < F.size(); vertex++){
    auto& neighbors = F[vertex];

    for_each(neighbors.begin(), neighbors.end(), [&](int neighbor){
      if(neighbor != -1 && nodeConnectedIdx[neighbor] != nodeConnectedIdx[vertex]){
        *find(F[vertex].begin(), F[vertex].end(), neighbor) = -1;
        *find(F[neighbor].begin(), F[neighbor].end(), vertex) = -1;
      }
    });
  }
  for(auto& neighbors: F){
    int originalsize = neighbors.size();
    auto newEnd = remove_if(neighbors.begin(), neighbors.end(), [&](int neighbor){ return neighbor == -1; });
    neighbors.erase(newEnd, neighbors.end());
    numSteps += originalsize - neighbors.size();
  }

  return numSteps/2;
}

int main(){
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  int numTests;
  cin >> numTests;

  while(numTests--){
      int n, m1, m2;
      cin >> n >> m1 >> m2;

      int numSteps{};
      vector<vector<int>> F(n+1);
      vector<vector<int>> G(n+1);
      vector<vector<int>> connectedG;
      vector<vector<int>> connectedF;
      vector<int>nodeConnectedIdG(n+1);
      vector<int>nodeConnectedIdxF(n+1);


      for(int i = 0; i < m1; i++){
          int n1, n2;
          cin >> n1 >> n2;
          F[n1].push_back(n2);
          F[n2].push_back(n1);
      }

      for(int i = 0; i < m2; i++){
          int n1, n2;
          cin >> n1 >> n2;
          G[n1].push_back(n2);
          G[n2].push_back(n1);
      }

      findConnected(G, connectedG, nodeConnectedIdG);
      numSteps += removeExtraEdges(F, connectedG, nodeConnectedIdG);

      findConnected(F, connectedF, nodeConnectedIdxF);
      numSteps += connectedF.size() - connectedG.size();

      cout << numSteps << '\n';
  }
}
Editor is loading...
Leave a Comment