CEOI 2004 Trial session Problem. Journey DFS

Posted OptimusPrime_L

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CEOI 2004 Trial session Problem. Journey DFS相关的知识,希望对你有一定的参考价值。

PROBLEM

http://www.oi.edu.pl/old/ceoi2004/problems/jou.pdf

分析

这题属于需要一些思考的题目。对于这道题目,我们要了解到这个图其实就是一棵树。如何想到这是树?题目中又这样几句话:

There are n cities in Byteland.

There are only n-1 roads, but connect the cities in such a way that is possible to travel from each city to any other city.

很容易发现这是典型的树的特征。当然,如果还不能看出来,随手画几个图就会发现,要满足这两个条件,这个图一定是一棵树。那么这道题的算法就是树的遍历,根据题目特征,很容易想到,利用DFS解决这道题目。

那么问题来了,如何计算最短路径呢?这个时候可能很难想到,那么可以简单地画几棵树。

经过不断尝试和总结(写一些数据),会发现:MinLength = EdgeLengthSum*2 - MaxEdgeLength(其中MaxEdgeLength是从出发点到某一需要拜访的点的最长距离)

其实仔细一想就明白了。这是一棵树,所以走到某一个点,再去下一个不在同一树枝上的点就要回头走到最小公共父亲。这意味着所有路都会走两边。因为题目中没有说要回到出发点,所以把距离出发点最远的点放在最后走,这样就不需要把这条最长边走两次了。于是就得出了上面这个公式。

程序

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int MAX = 50000 + 1;
 4 int EdgeCount, Head[MAX], dist[MAX], n, k, m;
 5 long long sum;
 6 bool visit[MAX];
 7 struct node
 8 {
 9     int Next, Aim, Weight;
10 }Edge[MAX];
11 void insert(int u, int v, int w)
12 {
13     Edge[++EdgeCount] = (node){Head[u],v,w};
14     Head[u] = EdgeCount;
15 }
16 void DFS(int u, int Father)
17 {
18     for (int i = Head[u]; i>0 ; i = Edge[i].Next)
19     {
20         int v = Edge[i].Aim;
21         if (Father == v)
22             continue;
23         dist[v] = dist[u]+Edge[i].Weight;
24         DFS(v,u);
25         if (visit[v])
26             sum += 2*Edge[i].Weight;
27     }
28 }
29 int main()
30 {
31     freopen("journey.in","r",stdin);
32     freopen("journey.out","w",stdout);
33     int Max_Edge = 0;
34     cin >> n >> k;
35     int u,v,w;
36     for (int i = 1; i <= n-1; i++)
37     {
38         cin >> u >> v >> w;
39         insert(u,v,w);
40         insert(v,u,w);
41     }
42     cin >> m;
43     for (int i = 1; i <= m; i++)
44     {
45         int c;
46         cin >> c;
47         visit[c] = true;
48     }
49     DFS(k,-1);
50     for (int i = 1; i <= n; i++)
51     {
52         if (visit[i])
53             Max_Edge = max(Max_Edge, dist[i]);
54     }
55     cout << sum-Max_Edge << endl;
56     return 0;
57 }

 

以上是关于CEOI 2004 Trial session Problem. Journey DFS的主要内容,如果未能解决你的问题,请参考以下文章

[CEOI 2004]Sweet

[CEOI2004]锯木厂选址

动态规划(斜率优化):[CEOI2004]锯木厂选址

bzoj 3027: [Ceoi2004]Sweet (生成函数)

[Ceoi2004]Journey

[CEOI2004]锯木厂选址