码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ 1509 [NOI2003]逃学的小孩

时间:2015-12-10 23:53:52      阅读:265      评论:0      收藏:0      [点我收藏+]

标签:

题意:给定一棵树,设A, B, C为树上的三个不相同的点,求出max{dist(A, B) + min{dist(C, A), dist(C, B)}} 

 

首先,如果dist(A,B)最大的话,很显然这是树上的一条最长链。也就是说,A和B是树上任意一条最长链的两个端点。

然后,我们有一个结论:树上某个点的最远点必定是树上任意一条最长链的两个端点中的一个。。

综合上面两个结论我们可以得到,当dist(A, B)和min{dist(C, A), dist(C, B)}同时取最大时,都与树上的最长链有关。。

毫不犹豫的求出最长链,并记录下它的两个端点A和B。然后枚举点C就可以啦~

求最长链的时间复杂度是O(N),求出A和B到每个点的距离的时间复杂度是O(N),枚举C的时间复杂度是O(N)。。因此总的时间复杂度就是O(N)

 

技术分享
  1 #include <queue>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <iostream>
  5 
  6 using namespace std;
  7 
  8 const size_t Max_N(200050);
  9 const size_t Max_M(400050);
 10 
 11 size_t N;
 12 
 13 unsigned int Total;
 14 unsigned int Head[Max_N];
 15 unsigned int To[Max_M];
 16 unsigned long long int Weight[Max_M];
 17 unsigned int Next[Max_M];
 18 
 19 inline
 20 unsigned long long int Max(const unsigned long long int &a, const unsigned long long int &b)
 21 {
 22     return a > b ? a : b;
 23 }
 24 
 25 inline
 26 unsigned long long int Min(const unsigned long long int &a, const unsigned long long int &b)
 27 {
 28     return a < b ? a : b;
 29 }
 30 
 31 inline
 32 void Add_Edge(const size_t &s, const size_t &t, const unsigned long long int &w)
 33 {
 34     ++Total, To[Total] = t, Weight[Total] = w, Next[Total] = Head[s], Head[s] = Total;
 35 }
 36 
 37 void init()
 38 {
 39     unsigned int M;
 40     size_t u, v;
 41     unsigned long long int w;
 42     
 43     cin >> N >> M;
 44     while (M--)
 45     {
 46         cin >> u >> v >> w;
 47         Add_Edge(u, v, w);
 48         Add_Edge(v, u, w);
 49     }
 50 }
 51 
 52 struct node
 53 {
 54     node(const unsigned int &a = 0, const unsigned long long int &b = 0) : now(a), wsum(b) {}
 55     unsigned int now;
 56     unsigned long long int wsum;
 57 };
 58 
 59 size_t A, B;//树上最长链的两个端点
 60 
 61 unsigned long long int Dist_A[Max_N], Dist_B[Max_N];
 62 //分别存储A到各个点的距离和B到各个点的距离 
 63 
 64 unsigned long long int Now_Max;
 65 bool In_Q[Max_N];
 66 
 67 void BFS_1()
 68 {
 69     Now_Max = 0ULL;
 70     queue<node> Q;
 71     Q.push(node(1, 0ULL));
 72     In_Q[1] = true;
 73     node Top;
 74     while (Q.size())
 75     {
 76         Top = Q.front();
 77         Q.pop();
 78         if (Top.wsum > Now_Max)
 79         {
 80             Now_Max = Top.wsum;
 81             A = Top.now;
 82         }
 83         for (size_t i = Head[Top.now];i;i = Next[i])
 84             if (!In_Q[To[i]])
 85             {
 86                 In_Q[To[i]] = true;
 87                 Q.push(node(To[i], Top.wsum + Weight[i]));
 88             }    
 89     }
 90 }
 91 
 92 void BFS_2()
 93 {
 94     Now_Max = 0ULL;
 95     memset(In_Q, false, sizeof(In_Q));
 96     queue<node> Q;
 97     Q.push(node(A, 0ULL));
 98     In_Q[A] = true;
 99     node Top;
100     while (Q.size())
101     {
102         Top = Q.front();
103         Q.pop();
104         if (Top.wsum > Now_Max)
105         {
106             Now_Max = Top.wsum;
107             B = Top.now;
108         }
109         for (size_t i = Head[Top.now];i;i = Next[i])
110             if (!In_Q[To[i]])
111             {
112                 In_Q[To[i]] = true;
113                 Q.push(node(To[i], Top.wsum + Weight[i]));
114             }    
115     }
116 }
117 
118 void BFS_A()//求出A到各个点的距离
119 {
120     memset(In_Q, false, sizeof(In_Q));
121     queue<unsigned int> Q;
122     Q.push(A);
123     In_Q[A] = true;
124     unsigned int Top;
125     while (Q.size())
126     {
127         Top = Q.front();
128         Q.pop();
129         for (size_t i = Head[Top];i;i = Next[i])
130             if (!In_Q[To[i]])
131             {
132                 In_Q[To[i]] = true;
133                 Q.push(To[i]);
134                 Dist_A[To[i]] = Dist_A[Top] + Weight[i]; 
135             }    
136     }
137 }
138 
139 void BFS_B()//求出B到各个点的距离
140 {
141     memset(In_Q, false, sizeof(In_Q));
142     queue<unsigned int> Q;
143     Q.push(B);
144     In_Q[B] = true;
145     unsigned int Top;
146     while (Q.size())
147     {
148         Top = Q.front();
149         Q.pop();
150         for (size_t i = Head[Top];i;i = Next[i])
151             if (!In_Q[To[i]])
152             {
153                 In_Q[To[i]] = true;
154                 Q.push(To[i]);
155                 Dist_B[To[i]] = Dist_B[Top] + Weight[i]; 
156             }    
157     }
158 }
159 
160 void Longest_Path()//求出最长链相关信息 
161 {
162     BFS_1();
163     BFS_2();
164     BFS_A();
165     BFS_B();
166 }
167 
168 void Get_Ans()
169 {
170     unsigned long long int Ans(0ULL);
171     for (size_t i = 1;i <= N;++i)
172         Ans = Max(Ans, Now_Max + Min(Dist_A[i], Dist_B[i]));
173     cout << Ans << endl;
174 }
175 
176 int main()
177 {
178     init();
179     
180     Longest_Path();
181     
182     Get_Ans();
183     
184     return 0;
185 }
BZOJ 1509

 

BZOJ 1509 [NOI2003]逃学的小孩

标签:

原文地址:http://www.cnblogs.com/Created-equal/p/5037486.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!