Codeforces Round #600 (Div. 2) D (貪心)

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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章