交流是一件很酷的事情
内存限制:512Mb
时间限制:1s
提交:6836
解决:621
题目描述
古老的王国中有 nn 个城市,这些城市之间由 mm 条道路相连接。现在又到了一年一度要举行交流会的时候,国王计划要在这些城市之间举行 kk 场交流会,每一场交流会在指定的两个城市间举行。
每个城市都有独一无二的思想,思想只有通过交流才能够流通,交流是一个相互并且可以传到的过程,比如说,如果城市 aa 和城市 bb 进行了交流,那么城市 aa 和城市 bb 就都拥有了对方的思想;如果城市 bb 和城市 cc 又有交流,那么城市 aa、bb、cc 就都有三份思想。
然而,你作为王国的军师,充分明白复习的重要性,在收到了国王的计划之后,你深知如果城市 aa 有了城市 bb 的思想,但是两个城市之间不能相互到达,即没有道路直接或者间接连接,那么他们就无法在交流会之后再次交流,在一段时间后他们就会忘记对方的思想。
国王想要知道在这些交流会很久之后,所有的城市中,最多能够有多少份思想、最少又能够有多少份思想。注意,每一个城市最初就有一个自己的想法。
输入
第一行两个整数 nn、mm,表示城市的数量和道路的数量。
接下来 mm 行,每行两个整数 uiui、vivi,表示城市 uiui 和 vivi 之间有一条道路相连接。
接下来一行一个整数 kk,表示交流会的数量。
接下来 kk 行,每行两个整数 xixi、yiyi,表示预计在城市 xixi 和城市 yiyi 之间举行一场交流会。
输出
输出一行两个整数 maxvmaxv 和 minvminv,表示城市最多的思想数量和最少的思想数量。
样例输入
8 6 1 3 1 4 2 7 3 5 3 6 3 8 5 1 3 1 8 2 3 2 7 4 6
样例输出
3 1
提示
数据规模与约束
对于 100%100% 的数据,2⩽n,m,k⩽2×105,1⩽ui,vi,xi,yi⩽n2⩽n,m,k⩽2×105,1⩽ui,vi,xi,yi⩽n,保证无重边无自环。
样例解释
所有交流会结束后,每座城市有的思想如下:
- 城市 1:1、2、3、7、8
- 城市 2:1、2、3、7、8
- 城市 3:1、2、3、7、8
- 城市 4:4、6
- 城市 5:5
- 城市 6:4、6
- 城市 7:1、2、3、7、8
- 城市 8:1、2、3、7、8
而在原图中,[1,3,8][1,3,8] 联通,[2,7][2,7] 联通,[4,6][4,6] 联通。
所以在足够长的时间过后,各个城市拥有的思想会维持在以下状态:
- 城市 1:1、3、8
- 城市 2:2、7
- 城市 3:1、3、8
- 城市 4:4、6
- 城市 5:5
- 城市 6:4、6
- 城市 7:2、7
- 城市 8:1、3、8
故城市最多有 3 份思想(城市 1、城市 3、城市 8),最少只有 1 份思想(城市 5)。
思路:维护两个并查集
代码:
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 5;
typedef pair<int, int> PII;
typedef long long LL;
int n, m, k;
int fa[N], fa1[N];
void init() {
for (int i = 1; i <= n; i ++ ) {
fa[i] = i;
fa1[i] = i;
}
}
int find(int x) {
return x == fa[x] ? fa[x] : fa[x] = find(fa[x]);
}
int find1(int x) {
return x == fa1[x] ? fa1[x] : fa1[x] = find1(fa1[x]);
}
int main() {
cin >> n >> m;
init();
int a, b;
for (int i = 1; i <= m; i ++ ) {
cin >> a >> b;
a = find(a); b = find(b);
fa[a] = b;
}
cin >> k;
for (int i = 1; i <= k; i ++ ) {
cin >> a >> b;
a = find1(a); b = find1(b);
fa1[a] = b;
}
map<pair<int, int>, int> mp;
for (int i = 1; i <= n; i ++ ) {
mp[{find1(i), find(i)}] ++;
}
int minNum = 0x3f3f3f3f, maxNum = 0;
for (auto t : mp) {
minNum = min(minNum, t.second);
maxNum = max(maxNum, t.second);
}
cout << maxNum << " " << minNum;
return 0;
}