Codeforces Round 738 (Div. 2) D2. Mocha and Diana (Hard Version)

server/2024/11/25 4:02:47/

题目

思路:

性质1:能在结点u,v添加边的充要条件是u,v在第一个图和第二个图都不连通

性质2:可以添加的边数等于 n - 1 - max(m1, m2),并且添加边的顺序不会影响结果(即 边(u,v)满足性质1,就可以直接添加,不会影响结果),证明如下:

        

对于hard version:先让所有可以与结点1连边的结点连边,然后对于结点2 ~ n,可以分为三类结点:在第一个图与结点1不连通,在第二个图与结点1连通(表示为01)、10 、11,(不存在00,若存在00,那么这个结点就会与结点1连边,变成11)。11的结点不能再连边,对答案无贡献,可以忽略;01的结点u可以与10的结点v连边,注意添加边(u,v)后,原本和u在第一个图中同一个连通块的结点(原本整个连通块的结点都是01)都会变成11,同理v在第二个图中所在连通块也是变成11,故对于每个连通块只找最高级祖先来连边。

#include <bits/stdc++.h>
using namespace std;
#define int long long
#define pb push_back
#define fi first
#define se second
#define lson p << 1
#define rson p << 1 | 1
const int maxn = 1e6 + 5, inf = 1e18, maxm = 4e4 + 5;
const int N = 1e6;
const int mod = 1e9 + 7;
// const int mod = 998244353;
//const __int128 mod = 212370440130137957LL;
//  int a[1005][1005];
// bool vis[505][505];
int n, m;
int a[maxn];
int b[maxn];
string s;struct DSU{vector<int> fa, siz;DSU(int n) : fa(n), siz(n, 1) {for(int i = 0; i < n; i++){fa[i] = i;}}int find(int x){if(x == fa[x]) return x;return fa[x] = find(fa[x]);}void merge(int u, int v){if(find(u) != find(v)){fa[find(u)] = find(v);}}
};
// struct Node{
//     int a, b;
//     // int val, id;
//     bool operator<(const Node &u)const{
//         
//     }
// }node[maxn];//long long ? maxn ? n? m?
void solve(){int res = 0;int k;int m1, m2;cin >> n >> m1 >> m2;int u, v;DSU t1(n + 5), t2(n + 5);for(int i = 1; i <= m1; i++){cin >> u >> v;t1.merge(u, v);} for(int i = 1; i <= m2; i++){cin >> u >> v;t2.merge(u, v);} res = n - 1 - max(m1, m2);cout << res << '\n';for(int i = 2; i <= n; i++){if(t1.find(i) != t1.find(1) && t2.find(i) != t2.find(1)){t1.merge(i, 1);t2.merge(i, 1);cout << 1 << ' ' << i << '\n';}}vector<int> vec[2];for(int i = 2; i <= n; i++){if(t1.find(i) != t1.find(1) && t1.find(i) == i){//01类的结点且是该连通块的最高级祖先 vec[0].pb(i);}if(t2.find(i) != t2.find(1) && t2.find(i) == i){//10类的结点且是该连通块的最高级祖先vec[1].pb(i);}}for(int i = 0; i < min(vec[0].size(), vec[1].size()); i++){cout << vec[0][i] << ' ' << vec[1][i] << '\n';}
}   signed main(){ios::sync_with_stdio(0);cin.tie(0);int T = 1;
//    cin >> T;while (T--){solve();}return 0;
}
?


http://www.ppmy.cn/server/38382.html

相关文章

秋招算法刷题8

20240422 2.两数相加 时间复杂度O&#xff08;max(m,n))&#xff0c;空间复杂度O&#xff08;1&#xff09; public ListNode addTwoNumbers(ListNode l1, ListNode l2) {ListNode headnull,tailnull;int carry0;while(l1!null||l2!null){int n1l1!null?l1.val:0;int n2l2!…

2024年化学材料、清洁能源与生物技术国际学术会议(ICCMCEB2024)

2024年化学材料、清洁能源与生物技术国际学术会议(ICCMCEB2024) 会议简介 2024国际化学材料、清洁能源和生物技术大会&#xff08;ICCMCEB2024&#xff09;将在长沙隆重举行。本次会议旨在汇聚来自世界各地的化学材料、清洁能源和生物技术领域的专家学者&#xff0c;共同探…

IO流-字符流

字节流&#xff1a;适合复制文件等&#xff0c;不适合读写文本文件 字符流&#xff1a;适合读写文本文件内容 FileReader:文件字符输入流 *作用&#xff1a;是以内存为基准&#xff0c;可以把文件中的数据以字符的形式读取到内存中去 构造器说明public FileReader(File file)创…

【吃透Java手写】2-Spring(下)-AOP-事务及传播原理

【吃透Java手写】Spring&#xff08;下&#xff09;AOP-事务及传播原理 6 AOP模拟实现6.1 AOP工作流程6.2 定义dao接口与实现类6.3 初始化后逻辑6.4 原生Spring的方法6.4.1 实现类6.4.2 定义通知类&#xff0c;定义切入点表达式、配置切面6.4.3 在配置类中进行Spring注解包扫描…

ISIS的基本概念

1.ISIS概述 IS-IS是一种链路状态路由协议&#xff0c;IS-IS与OSPF在许多方面非常相似&#xff0c; 例如运行IS-IS协议的直连设备之间通过发送Hello报文发现彼此&#xff0c;然后建立邻接关系&#xff0c;并交互链路状态信息。 CLNS由以下三个部分组成&#xff1a; CLNP&#xf…

QT设计模式:桥接模式

基本概念 桥接模式是一种结构型设计模式&#xff0c;它将抽象部分与它的实现部分分离&#xff0c;使得它们可以独立地变化&#xff0c;而不会相互影响。 需要实现的结构如下&#xff1a; 抽象部分&#xff08;Abstraction&#xff09;&#xff1a;定义了抽象类的接口&#x…

QT--day3

1、mywidget.h #ifndef MYWIDGET_H #define MYWIDGET_H #include <QWidget> #include<QIcon> //图标类 #include<QLabel> //标签类 #include<QMovie> //动图类 #include<QLineEdit> //行编辑器类 #include<QPushButton> //按钮类 #include…

firewall-cmd --list-all详解

含义 在 firewall-cmd --list-all 命令的输出结果中&#xff0c;涉及到的每行的含义如下&#xff1a; “target”&#xff1a;表示当前 Firewalld 防火墙的默认目标&#xff0c;可以是 “ACCEPT”、“DROP” 或 “REJECT”。 “DROP”&#xff0c;表示拒绝所有流量&#xff1…