Codeforces 592D Super M 【求解包含若干个点的最小树 + 树的直径】
2015-11-08 12:40
489 查看
D. Super M
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
Ari the monster is not an ordinary monster. She is the hidden identity of Super M, the Byteforces’ superhero. Byteforces is a country that consists of n cities,
connected by n - 1 bidirectional roads. Every road connects exactly two distinct cities, and the whole road system is designed in
a way that one is able to go from any city to any other city using only the given roads. There are m cities being attacked by humans.
So Ari... we meant Super M have to immediately go to each of the cities being attacked to scare those bad humans. Super M can pass from one city to another only using the given roads. Moreover, passing through one road takes her exactly one kron - the time
unit used in Byteforces.
However, Super M is not on Byteforces now - she is attending a training camp located in a nearby country Codeforces. Fortunately, there is a special device in Codeforces that allows her to instantly teleport from Codeforces to any city of Byteforces. The way
back is too long, so for the purpose of this problem teleportation is used exactly once.
You are to help Super M, by calculating the city in which she should teleport at the beginning in order to end her job in the minimum time (measured in krons). Also, provide her with this time so she can plan her way back to Codeforces.
Input
The first line of the input contains two integers n and m (1 ≤ m ≤ n ≤ 123456)
- the number of cities in Byteforces, and the number of cities being attacked respectively.
Then follow n - 1 lines, describing the road system. Each line contains two city numbers ui and vi (1 ≤ ui, vi ≤ n)
- the ends of the roadi.
The last line contains m distinct integers - numbers of cities being attacked. These numbers are given in no particular order.
Output
First print the number of the city Super M should teleport to. If there are many possible optimal answers, print the one with the lowest city number.
Then print the minimum possible time needed to scare all humans in cities being attacked, measured in Krons.
Note that the correct answer is always unique.
Sample test(s)
input
output
input
output
Note
In the first sample, there are two possibilities to finish the Super M's job in 3 krons. They are:
and
.
However, you should choose the first one as it starts in the city with the lower number.
花了1小时,终于AC了。
题意:给定一棵n节点的树,需要从某个点出发遍历m个指定的点。让你输出编号最小的起点和需要的最少步数。
经过一条边算一步。
思路:考虑对一棵树节点的遍历。我们从任意一个节点出发,需要(边数*2)步才能遍历所有的节点并回到出发点。但是如果我们的目的仅仅是遍历所有点(不需要返回),那么步数就是(边数*2) - 树的直径。
这样的话我们便可以在原树上建立一棵包含m个节点的最小树,然后结果就是最小树的边数*2 - 最小树的直径。
至于建立最小树,可以通过DFS实现。我们标记所有需要遍历的点,在回溯的过程中将标记上传到节点的父亲上。因为我们要遍历这个点,必须要遍历它的父亲,同样遍历它的父亲...依次上传标记就可以把树建立出来。
注意:求树的直径时,要不断更新S-T端点,因为构成一棵树直径的点 并不是唯一的。
AC代码:
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output
Ari the monster is not an ordinary monster. She is the hidden identity of Super M, the Byteforces’ superhero. Byteforces is a country that consists of n cities,
connected by n - 1 bidirectional roads. Every road connects exactly two distinct cities, and the whole road system is designed in
a way that one is able to go from any city to any other city using only the given roads. There are m cities being attacked by humans.
So Ari... we meant Super M have to immediately go to each of the cities being attacked to scare those bad humans. Super M can pass from one city to another only using the given roads. Moreover, passing through one road takes her exactly one kron - the time
unit used in Byteforces.
However, Super M is not on Byteforces now - she is attending a training camp located in a nearby country Codeforces. Fortunately, there is a special device in Codeforces that allows her to instantly teleport from Codeforces to any city of Byteforces. The way
back is too long, so for the purpose of this problem teleportation is used exactly once.
You are to help Super M, by calculating the city in which she should teleport at the beginning in order to end her job in the minimum time (measured in krons). Also, provide her with this time so she can plan her way back to Codeforces.
Input
The first line of the input contains two integers n and m (1 ≤ m ≤ n ≤ 123456)
- the number of cities in Byteforces, and the number of cities being attacked respectively.
Then follow n - 1 lines, describing the road system. Each line contains two city numbers ui and vi (1 ≤ ui, vi ≤ n)
- the ends of the roadi.
The last line contains m distinct integers - numbers of cities being attacked. These numbers are given in no particular order.
Output
First print the number of the city Super M should teleport to. If there are many possible optimal answers, print the one with the lowest city number.
Then print the minimum possible time needed to scare all humans in cities being attacked, measured in Krons.
Note that the correct answer is always unique.
Sample test(s)
input
7 2 1 2 1 3 1 4 3 5 3 6 3 7 2 7
output
2 3
input
6 4 1 2 2 3 2 4 4 5 4 6 2 4 5 6
output
2 4
Note
In the first sample, there are two possibilities to finish the Super M's job in 3 krons. They are:
and
.
However, you should choose the first one as it starts in the city with the lower number.
花了1小时,终于AC了。
题意:给定一棵n节点的树,需要从某个点出发遍历m个指定的点。让你输出编号最小的起点和需要的最少步数。
经过一条边算一步。
思路:考虑对一棵树节点的遍历。我们从任意一个节点出发,需要(边数*2)步才能遍历所有的节点并回到出发点。但是如果我们的目的仅仅是遍历所有点(不需要返回),那么步数就是(边数*2) - 树的直径。
这样的话我们便可以在原树上建立一棵包含m个节点的最小树,然后结果就是最小树的边数*2 - 最小树的直径。
至于建立最小树,可以通过DFS实现。我们标记所有需要遍历的点,在回溯的过程中将标记上传到节点的父亲上。因为我们要遍历这个点,必须要遍历它的父亲,同样遍历它的父亲...依次上传标记就可以把树建立出来。
注意:求树的直径时,要不断更新S-T端点,因为构成一棵树直径的点 并不是唯一的。
AC代码:
#include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <algorithm> #include <queue> #include <stack> #include <map> #include <vector> #define INF 0x3f3f3f3f #define eps 1e-8 #define MAXN (123456+10) #define MAXM (50000000) #define Ri(a) scanf("%d", &a) #define Rl(a) scanf("%lld", &a) #define Rf(a) scanf("%lf", &a) #define Rs(a) scanf("%s", a) #define Pi(a) printf("%d\n", (a)) #define Pf(a) printf("%lf\n", (a)) #define Pl(a) printf("%lld\n", (a)) #define Ps(a) printf("%s\n", (a)) #define W(a) while(a--) #define CLR(a, b) memset(a, (b), sizeof(a)) #define MOD 1000000007 #define LL long long #define lson o<<1, l, mid #define rson o<<1|1, mid+1, r #define ll o<<1 #define rr o<<1|1 using namespace std; struct Edge{ int from, to, next; }; Edge edge[MAXN*2], Tedge[MAXN*2]; int head[MAXN], edgenum; int Thead[MAXN], Tedgenum; void init(){ edgenum = 0; CLR(head, -1); } void addEdge(int u, int v) { Edge E = {u, v, head[u]}; edge[edgenum] = E; head[u] = edgenum++; } void initTree(){ Tedgenum = 0; CLR(Thead, -1); } void addTree(int u, int v) { Edge E = {u, v, Thead[u]}; Tedge[Tedgenum] = E; Thead[u] = Tedgenum++; } bool vis[MAXN]; int mark, pre[MAXN]; void DFS(int u, int fa) { for(int i = head[u]; i != -1; i = edge[i].next) { int v = edge[i].to; if(v == fa) continue; DFS(v, u); pre[v] = u;//记录前驱 if(vis[v]) { addTree(u, v); addTree(v, u); vis[pre[v]] = true;//上传标记 } } } void getMap() { int n, m; Ri(n); Ri(m); int a, b; init(); for(int i = 1; i < n; i++) Ri(a), Ri(b), addEdge(a, b), addEdge(b, a); CLR(vis, false); for(int i = 1; i <= m; i++) { Ri(a), vis[a] = true; if(i == m) mark = a; } } int dist[MAXN]; int S, T, len; void BFS(int s, int &node) { queue<int> Q; CLR(dist, 0); len = 0; CLR(vis, false); node = s; dist[s] = 0; Q.push(s); vis[s] = true; while(!Q.empty()) { int u = Q.front(); Q.pop(); for(int i = Thead[u]; i != -1; i = Tedge[i].next) { Edge E = Tedge[i]; if(!vis[E.to]) { dist[E.to] = dist[u] + 1; Q.push(E.to); vis[E.to] = true; if(dist[E.to] > len) { len = dist[E.to]; node = E.to; } if(dist[E.to] == len)//更新最小的S端点 因为这WA了一次 node = min(node, E.to); } } } } void solve() { getMap(); initTree(); DFS(mark, -1); BFS(mark, S); BFS(S, T); int start = min(S, T); Pi(start); Pi(Tedgenum - len); } int main() { solve(); return 0; }
相关文章推荐
- Codeforces 593B Anton and Lines 【思维】
- Codeforces 593A 2Char 【思维】
- Dom4j介绍与接口说明
- IMP-00038:无法转换为环境字符集句柄
- lightoj 1410 - Consistent Verdicts 【思维】
- lightoj 1369 - Answering Queries 【思维】
- lightoj 1354 - IP Checking 【进制水题】
- lightoj 1297 - Largest Box 【函数最值】
- lightoj 1294 - Positive Negative Sign 【基础计数】
- lightoj 1349 - Aladdin and the Optimal Invitation 【中位数的运用】
- lightoj 1311 - Unlucky Bird 【物理基础】
- HDU 5514 Frogs (2015沈阳F题&&容斥+剪枝)
- Linux_NetworkManager_RHEL7
- Oracle dmp文件导入(还原)到不同的表空间和不同的用户下
- 【DirectX 9.0c入门教程】之一 开发环境搭建:安装vs2008 sp1和DirectX SDK
- lightoj 1319 - Monkey Tradition 【CRT】
- mysql学习笔记(3)
- lightoj 1179 - Josephus Problem 【约瑟夫环】
- 驱动开发(4)内核中的内存分配和错误码
- Android笔记—应用更新