XCPC集训47补题

H - The Tag Game

题目:

Alice got tired of playing the tag game by the usual rules so she offered Bob a little modification to it. Now the game should be played on an undirected rooted tree of n vertices. Vertex 1 is the root of the tree.
Alice starts at vertex 1 and Bob starts at vertex x (x ≠ 1). The moves are made in turns, Bob goes first. In one move one can either stay at the current vertex or travel to the neighbouring one.
The game ends when Alice goes to the same vertex where Bob is standing. Alice wants to minimize the total number of moves and Bob wants to maximize it.
You should write a program which will determine how many moves will the game last.

Input

The first line contains two integer numbers n and x (2 ≤ n ≤ 2·10^5, 2 ≤ x ≤ n).
Each of the next n - 1 lines contains two integer numbers a and b (1 ≤ a, b ≤ n) — edges of the tree. It is guaranteed that the edges form a valid tree.

Output

Print the total number of moves Alice and Bob will make.

Sample 1

Input

4 3
1 2
2 3
2 4

Output

4

Sample 2

Input

5 2
1 2
2 3
3 4
2 5

Output

6

分析:

B必定在A的子树上,为了让步数最少,A定是要朝着B的方向走的,为了让步数最大,B定是要往最深的方向走。
因此,可以分别求出A、B到每个点的距离d1、d2, 如果d1>d2 则说明可行(可自行模拟)。

代码:

/*
	qwq!
*/

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <map>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <cmath>
#include <unordered_map>
using namespace std;
#define pb push_back
#define pu push
#define fi first
#define se second
#define LL long long
typedef pair<int,int> PII;
const int INF = 0x3f3f3f3f;
const int N = 2e5 + 10, M = N << 1;
int h[N], e[M], ne[M], d1[N], d2[N], idx;


int read () {
	int k=0,f=1;
	char c=getchar ();
	while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar ();}
	while (c>='0'&&c<='9') {k=k*10+c-'0';c=getchar ();}
	return k*f;
}

void add(int a, int b) {
	e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}

void dfs1(int u, int f, int s) {    // 求B到各点的距离 
	d1[u] = s;
	for(int i = h[u]; ~i; i = ne[i]) {
		int j = e[i];
		if(j == f) continue;
		dfs1(j, u, s + 1);
	}
} 

void dfs2(int u, int f, int s) {	// 求A到各点的距离 
	d2[u] = s;
	for(int i = h[u]; ~i; i = ne[i]) {
		int j = e[i];
		if(j == f) continue;
		dfs2(j, u, s + 1);
	}
}

int main() {
	int n = read(), x = read();
	memset(h, -1, sizeof h);
	for(int i = 1; i < n; i++) {
		int a = read(), b = read();
		add(a, b), add(b, a);
	}
	dfs1(x, -1, 0);
	dfs2(1, -1, 0);
	
	int ans = 0;
	for(int i = 1; i <= n; i++) {
		if(d1[i] < d2[i]) ans = max(ans, d2[i] * 2);  
	} 
	cout << ans << endl;
	return 0;
}

J - Harmonious Graph

题目:

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) such that 1l<m<rn , if there exists a path going from node l to node r, then there exists a path going from node l to node m.
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),,(r1)too.
What is the minimum number of edges we need to add to make the graph harmonious?

Input

The first line contains two integers n and m (3n200000 and 1m200000).
The i-th of the next m lines contains two integers ui and vi (1ui,vin,uivi), that mean that there's an edge between nodes u and v.
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.

Sample 1

Input

14 8
1 2
2 7
3 4
6 3
5 7
3 8
6 8
11 12

Output

1

Sample 2

Input

200000 3
7 9
9 8
4 5

Output

0

分析:

若1->3->7,则应当有1->2,1->4,1->5,1->6,即1-7中所有的点都应该在一个连通块中。因此可以让每个连通块中的父亲节点为连通块的最大值,然后枚举每一个小于当前父节点的点判断其父节点是否小于该父节点,如果不等,则应该连通。也就是加一条边。

代码:

/*
	qwq!
*/

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#include <map>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <cmath>
#include <unordered_map>
using namespace std;
#define pb push_back
#define pu push
#define fi first
#define se second
#define LL long long
typedef pair<int,int> PII;
const int INF = 0x3f3f3f3f;
const int N = 2e5 + 10;
int f[N];


int read () {
	int k=0,f=1;
	char c=getchar ();
	while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar ();}
	while (c>='0'&&c<='9') {k=k*10+c-'0';c=getchar ();}
	return k*f;
}

int find(int x) {
	if(x != f[x]) f[x] = find(f[x]);
	return f[x];
}

void merge(int a, int b) {
	a = find(a), b = find(b);
	if(a != b) {
		if(a < b) swap(a, b);
		f[b] = a;
	}
}
int main() {
	int n = read(), m = read();
	for(int i = 1; i <= n; i++) f[i] = i;
	while(m--) {
		int a = read(), b = read();
		merge(a, b);
	}
	int ans = 0;
	int fa = 0;
	int t = 1;
	while(t <= n) {
		fa = find(t);
		for(int i = t + 1; i <= fa; i++) {
			int x = find(i);
			if(x != fa) {
				ans++;
				merge(x, fa);
				fa = max(fa, x);
			}
		}
		t = fa + 1;
	}
	cout << ans << endl;
	return 0;
}
posted @   飘向远方丶  阅读(29)  评论(0编辑  收藏  举报
(评论功能已被禁用)
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App
点击右上角即可分享
微信分享提示