SGU 507 Treediff

这个题目  其实可以暴力  用两个 set 合并; 每次放进去一个元素只要找到这个元素第一个比他大的元素和最后一个比他小的元素;然后更新最优值;

证明为什么不会超时;  假如最后集合的小的为 S1,大的集合为S2; 这样将 S1合并到S2; 这样S2 》= S1×2;合并 t 次后 大小就成了 S1×(2^t); 但是集合大小只有N 个元素  也就是说  N 》= S1×(2^t ); 但S1等于1时 也就是说一个元素最多合并t 《= log(N) 次;

 1 #include<iostream>
 2 #include<stdio.h>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cmath>
 6 #include<set>
 7 using namespace std;
 8 
 9 struct date{
10    int v,next;
11 }edge[51234]; int N,M,total,head[51234];
12 void add_edge( int u,int v ){
13     edge[total].v = v;
14     edge[total].next = head[u];
15     head[u] = total++;
16 }
17 inline int min(int a,int b){return a<b?a:b;}
18 inline int max(int a,int b){return a>b?a:b;}
19 set<int>s[51234]; int res[51234]; int tab[51234];
20 int dfs( int sta )
21 {
22     bool fell = false; bool fall = false; int ans = 2147483647;
23     for( int i = head[sta]; i != -1; i = edge[i].next )
24     {
25         int v = edge[i].v;  ans = min( ans,dfs( v ) );   set<int>::iterator it,now;
26         if( !fell ){ tab[sta] = tab[v]; res[sta] = 2147483647; fell = true; continue; }
27         int len1 = s[tab[sta]].size(); int len2 = s[tab[v]].size();
28         if( len1 > len2 ){
29             for( it = s[tab[v]].begin(); it != s[tab[v]].end(); it++ )
30             {
31                  now = s[tab[sta]].lower_bound(*it);
32                  if( now != s[tab[sta]].end() ){ ans = min( ans,*now-*it ); }
33                  if( now != s[tab[sta]].begin() ){ now--;ans = min( ans,*it-*now ); }
34                  if( s[tab[sta]].find(*it) == s[tab[sta]].end() ) s[tab[sta]].insert(*it);
35             }
36         }else {
37             for( it = s[tab[sta]].begin(); it != s[tab[sta]].end(); it++ )
38             {
39                  now = s[tab[v]].lower_bound(*it);
40                  if( now != s[tab[v]].end() ){ ans = min( ans,*now-*it ); }
41                  if( now != s[tab[v]].begin() ){ ans = min( ans,*it-*(--now) ); }
42                  if( s[tab[v]].find(*it) == s[tab[v]].end() )s[tab[v]].insert(*it);
43             }
44             tab[sta] = tab[v];
45         }
46     }
47     res[sta] = ans; return ans;
48 }
49 int main( )
50 {
51     while( scanf("%d%d",&N,&M) != EOF )
52     {
53         for( int i = 0; i <= N; i++ )s[i].clear();
54         for( int i = 0; i <= N; i++ )tab[i] = i;
55           total = 0; int k = N-M+1; memset( head,-1,sizeof(head) );
56         for( int i = 2; i <= N ;i++ ){
57             int v; scanf("%d",&v);
58             add_edge( v,i );
59         }
60         for( int i = 1; i <= M; i++ ){
61             int num; scanf("%d",&num); s[k++].insert(num);
62         }
63         dfs( 1 );
64         printf("%d",res[1]);
65         for( int i = 2; i <= N-M; i++ )
66         printf(" %d",res[i]);
67         puts("");
68     }
69     return 0;
70 }

 

 

posted on 2013-11-23 19:14  浪舟  阅读(498)  评论(0编辑  收藏  举报

导航