/* VIM: let b:cf5build="clang -std=c++20 -O2 -pthread -lstdc++ -I. {SRC} -o {OUT}" VIM: let b:cf5run="{OUT}" */ #include #include #include #include #include /* std::unordered_map> */ using contacts_type = std::unordered_map>; using emails_type = std::unordered_map>; void all_contacts( const std::string& contact, std::unordered_set& visited_contacts, const contacts_type& contacts, const emails_type& emails, std::unordered_set& merged_emails) { visited_contacts.insert(contact); for (const auto& email: contacts[contact]){ if (merged_emails.count(email)==0){ merged_emails.insert(email); for (const auto& merging_contacts : emails[email]){ all_contacts(merging_contacts, visited_contacts, contacts, emails, merged_emails ); } } } } contacts_type merge( const contacts_type& contacts){ std::unordered_map> emails; for (const auto& contact : contacts){ for (const auto& email : contact.second){ emails[email].insert(contact.first); } } contacts_type merged_contacts; std::unordered_set visited_contacts; for (const auto& contact : contacts){ if (visited_contacts.count(contact.first) == 0){ auto& merged_emails = merged_contacts[contact.first]; all_contacts(contact.first, visited_contacts, contacts, emails, merged_emails); } } return merged_contacts; } int main ( void ) {try{ auto begin = std::chrono::high_resolution_clock::now(); //...... auto end = std::chrono::high_resolution_clock::now(); std::chrono::duration seconds = end - begin; std::cout << "Time: " << seconds.count() << std::endl; return 0; } catch ( const std::exception& e ) { std::cerr << std::endl << "std::exception(\"" << e.what() << "\")." << std::endl; return 2; } catch ( ... ) { std::cerr << std::endl << "unknown exception." << std::endl; return 1; }}