D. Harmonious Graph
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output
You're given an undirected graph with nn nodes and mm edges. Nodes are numbered from 11 to nn.
The graph is considered harmonious if and only if the following property holds:
- For every triple of integers (l,m,r)(l,m,r) such that 1≤l<m<r≤n1≤l<m<r≤n, if there exists a path going from node ll to node rr, then there exists a path going from node ll to node mm.
In other words, in a harmonious graph, if from a node ll we can reach a node rr through edges (l<rl<r), then we should able to reach nodes (l+1),(l+2),…,(r−1)(l+1),(l+2),…,(r−1) too.
What is the minimum number of edges we need to add to make the graph harmonious?
Input
The first line contains two integers nn and mm (3≤n≤200 0003≤n≤200 000 and 1≤m≤200 0001≤m≤200 000).
The ii-th of the next mm lines contains two integers uiui and vivi (1≤ui,vi≤n1≤ui,vi≤n, ui≠viui≠vi), that mean that there's an edge between nodes uu and vv.
It is guaranteed that the given graph is simple (there is no self-loop, and there is at most one edge between every pair of nodes).
Output
Print the minimum number of edges we have to add to the graph to make it harmonious.
Examples
input
Copy
14 8
1 2
2 7
3 4
6 3
5 7
3 8
6 8
11 12
output
Copy
1
input
Copy
200000 3
7 9
9 8
4 5
output
Copy
0
Note
In the first example, the given graph is not harmonious (for instance, 1<6<71<6<7, node 11 can reach node 77 through the path 1→2→71→2→7, but node 11 can't reach node 66). However adding the edge (2,4)(2,4) is sufficient to make it harmonious.
In the second example, the given graph is already harmonious.
题目大意 :
输入一个包含N个点的无向图,现在规定一个和谐的图满足, 图中最大编号 - 最小编号 + 1 = 该连通块的点数, 输出至少需要添加多少条边,可以使整张图和谐
思路 :
题目已经给出思路了, 不断添加边使该连通块的点数 = 最大编号 - 最小编号 + 1, 所以先遍历整张图, 将每个连通块的最小编号,最大编号,点的个数记录下来, 剩下就是贪心的思想, 用优先队列存下每个连通块的信息, 按照每个连通块最小编号排序, 如果该连通块已经满足, 那么就不需要加边,并且易知排序在该连通块之前的连通块都满足和谐, 所以如果当前的连通块不和谐,那么将他与下一个连通块合并到一起, 如果仍然不和谐, 继续加入到队列中, 每次操作添加边数量 + 1、
Accepted code
#include<bits/stdc++.h>
using namespace std;
#define sc scanf
#define ls rt << 1
#define rs ls | 1
#define Min(a, b) a = min(a, b)
#define Max(a, b) a = max(a, b)
#define ALL(a) (a).begin(), (a).end()
#define MEM(a, b) memset(a, b, sizeof(a))
#define SZ(a) (a).size()
#define lowbit(x) (x) & -(x)
#define P2(x) (x) * (x)
typedef long long ll;
const int MAXN = 2e5 + 100;
const int INF = 0x3f3f3f3f;
struct node
{
int x, y, num;
bool operator < (const node &oth) const
{
return x > oth.x;
}
};
priority_queue <node> q;
vector <int> e[MAXN << 1];
int n, m, tot, sum, min_, max_, ans;
bool vis[MAXN];
void dfs(int x, int fa) {
vis[x] = true;
Min(min_, x); Max(max_, x);
sum++;
for (auto it : e[x]) {
int vi = it;
if (vi == fa || vis[vi]) continue;
dfs(vi, x);
}
}
int main()
{
cin >> n >> m;
for (int i = 0; i < m; i++) {
int ui, vi; sc("%d %d", &ui, &vi);
e[ui].push_back(vi);
e[vi].push_back(ui);
}
for (int i = 1; i <= n; i++) {
if (!vis[i]) {
min_ = INF, max_ = -INF, sum = 0;
dfs(i, i);
q.push({ min_, max_, sum }); // 记录最小编号,最大编号,数量
}
}
while (!q.empty() && SZ(q) > 1) {
node fir = q.top(); q.pop();
if (fir.num == fir.y - fir.x + 1 || q.empty()) continue; // 已经和谐
node sec = q.top(); q.pop();
int mi = min(fir.x, sec.x);
int ma = max(fir.y, sec.y);
int s = fir.num + sec.num;
if (s != ma - mi + 1) q.push({ mi, ma, s }); // 不和谐继续加入队列
ans++;
}
cout << ans << endl;
return 0;
}