列表

详情


NC200321. Gangstar

描述

在忙碌的ICPC训练后, Vanis和Qiy玩起了警匪游戏。

游戏在一棵具有n个节点的无向树上进行,Qiy作为警察,想要尽早的抓到Vanis。而Vanis作为匪徒,想要尽量逃脱Qiy的追捕。奈何“天网恢恢,疏而不漏”,即使强如Vanis,也只能尽量拖延自己被抓到的时间。

初始时,Qiy处于1号点,Vanis处于x号点。每2秒种,两者可以选择移动1步到相邻的点或留在原地(按上文中提到的策略行动)。当二人在某个时间处于同一顶点时,Qiy便追到了Vanis。Vanis会尽量逃离Qiy的追逐,而Qiy想尽快追到Vanis。作为吃瓜群众的选手们,你们知道Qiy最少要花多少时间才能追捕到Vanis吗?


输入描述

第一行输入两个正整数n和x,分别表示树的顶点个数以及Vanis初始所在的位置。
接下来n - 1行每行输入两个正整数u和v,表示有一条边连接顶点u和顶点v。

数据规范:
* .
* 保证输入的顶点和边构成一棵无向树。

输出描述

输出一个整数,表示Qiy追到Vanis所需的时间。

示例1

输入:

4 3
1 2
2 3
2 4

输出:

4

说明:

2s时,vanis停留在3号点,Qiy移动到2号点
4s时,vanis停留在3号点,Qiy移动到3号点,抓捕成功

示例2

输入:

5 2
1 2
2 3
3 4
2 5

输出:

6

说明:

2s时,vanis移动到3号点,Qiy移动到2号点
4s时,vanis移动到4号点,Qiy移动到3号点
6s时,vanis停留在4号点,Qiy移动到4号点,抓捕成功

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 327ms, 内存消耗: 22184K, 提交时间: 2020-06-14 14:53:09

#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
const int maxn = 2e5 + 111;
vector<int>G[maxn];
void add(int x, int y) {
	G[x].push_back(y);
}
int f[maxn];
int dep[maxn];
int dfs(int x, int fa, int d) {
	dep[x] = d;
	f[x] = fa;
	for (int p : G[x]) {
		if (p == fa) continue;
		dfs(p, x, d + 1);
	}
	return 0;
}

int de[maxn];
int ans = 0;


int dfs1(int x, int fa, int d) {
	ans = max(d, ans);
	for (int p : G[x]) {
		if (p == f[x]) continue;
		dfs1(p, x, d + 1);
	}
	return 0;
}

int main() {
	int n, k;
	cin >> n >> k;
	if (n == 1) {
		cout << 0 << endl;
		return 0;
	}
	for (int i = 1; i < n; i++) {
		int x, y;
		cin >> x >> y;
		add(x, y);
		add(y, x);
	}
	dfs(1, -1, 0);
	int a = k;

	int len = (dep[k] - 1) / 2;
	for (int i = 0; i < len; i++) k = f[k];

	int root = k;

	dfs1(root, f[root], 0);
	ans++;
	ans += len;
	if (dep[a] % 2 == 0) {
		ans++;
	}
	
	cout << 2*ans << endl;
	return 0;
}
/*
10 5
1 2
2 3
3 4
4 5
4 6
6 7
3 8
8 9
9 10


*/

C++11(clang++ 3.9) 解法, 执行用时: 304ms, 内存消耗: 21456K, 提交时间: 2020-07-05 11:35:47

#include <bits/stdc++.h>
using namespace std;
#define N 202020
vector<int> v[N];
int n, x, dep[N], ans;
void go(int now, int prt, int ndep) {
	dep[now] = ndep;
	for (int son : v[now]) {
		if (son == prt) continue;
		go(son, now, ndep + 1);
	}
}
int bdr;
void go2(int now, int prt) {
	if (dep[now] <= bdr) return;
	ans = max(ans, dep[now]);
	for (int son : v[now]) {
		if (son == prt) continue;
		go2(son, now);
	}
}
int main() {
	cin >> n >> x;
	for (int i = 1; i < n; i++) {
		int a, b;
		cin >> a >> b;
		v[a].push_back(b);
		v[b].push_back(a);
	}
	go(1, 1, 0);
	bdr = dep[x] / 2;
	go2(x, x);
	printf("%d\n", ans << 1);
}

上一题