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 , 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
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
The i-th of the next m lines contains two integers and , 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;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App