Poj--3728(LCA,修改tarjan)
2014-10-28 13:37:43
思路:LCA好题。尚认为自己没有实力写出题解,和大牛讨论下再写吧。
1 /************************************************************************* 2 > File Name: 3728.cpp 3 > Author: Nature 4 > Mail: 564374850@qq.com 5 > Created Time: Sun 26 Oct 2014 04:23:07 PM CST 6 ************************************************************************/ 7 8 #include <cstdio> 9 #include <cstring> 10 #include <cstdlib> 11 #include <cmath> 12 #include <vector> 13 #include <map> 14 #include <set> 15 #include <stack> 16 #include <queue> 17 #include <iostream> 18 #include <algorithm> 19 using namespace std; 20 #define lp (p << 1) 21 #define rp (p << 1|1) 22 #define getmid(l,r) (l + (r - l) / 2) 23 #define MP(a,b) make_pair(a,b) 24 typedef long long ll; 25 const int INF = 1 << 30; 26 const int maxn = 100010; 27 28 int N,Q; 29 int w[maxn],qa[maxn],qb[maxn]; 30 int first[maxn],next[maxn],ver[maxn],ecnt; 31 int f1[maxn],n1[maxn],v1[maxn],id1[maxn],e1; 32 int fa[maxn],vis[maxn],tmin[maxn],tmax[maxn],st[maxn],ed[maxn]; 33 int ans[maxn]; 34 vector<int> g[maxn]; 35 36 void Init(){ 37 memset(first,-1,sizeof(first)); 38 memset(f1,-1,sizeof(f1)); 39 for(int i = 1; i <= N; ++i) 40 g[i].clear(); 41 ecnt = 0; 42 } 43 44 void Add_edge(int u,int v){ 45 next[++ecnt] = first[u]; 46 ver[ecnt] = v; 47 first[u] = ecnt; 48 } 49 50 void Add_edge1(int u,int v,int id){ 51 n1[++e1] = f1[u]; 52 v1[e1] = v; 53 id1[e1] = id; 54 f1[u] = e1; 55 } 56 57 int Find(int x){ 58 return fa[x] == x ? x : Find(fa[x]); 59 } 60 61 void Union(int u,int v){ 62 int x = Find(u); 63 int y = Find(v); 64 if(x != y) 65 fa[y] = x; 66 } 67 68 int Update(int x){ 69 if(fa[x] == x) 70 return x; 71 int y = fa[x]; 72 fa[x] = Update(fa[x]); 73 st[x] = max(max(st[y],st[x]),tmax[y] - tmin[x]); 74 ed[x] = max(max(ed[y],ed[x]),tmax[x] - tmin[y]); 75 tmax[x] = max(tmax[x],tmax[y]); 76 tmin[x] = min(tmin[x],tmin[y]); 77 return fa[x]; 78 } 79 80 void Tarjan(int p,int pre){ 81 fa[p] = p; 82 vis[p] = 1; 83 for(int i = f1[p]; ~i; i = n1[i]){ 84 int v = v1[i]; 85 if(vis[v]){ 86 int y = Find(v); 87 g[y].push_back(id1[i]); 88 } 89 } 90 for(int i = first[p]; ~i; i = next[i]){ 91 int v = ver[i]; 92 if(v != pre){ 93 Tarjan(v,p); 94 Union(p,v); 95 } 96 } 97 for(int i = 0; i < g[p].size(); ++i){ 98 int id = g[p][i]; 99 int u = qa[id],v = qb[id]; 100 Update(u); 101 Update(v); 102 ans[id] = max(max(st[u],ed[v]),tmax[v] - tmin[u]); 103 } 104 } 105 106 int main(){ 107 int a,b; 108 scanf("%d",&N); 109 Init(); 110 for(int i = 1; i <= N; ++i){ 111 scanf("%d",w + i); 112 tmax[i] = tmin[i] = w[i]; 113 st[i] = ed[i] = 0; 114 } 115 for(int i = 1; i < N; ++i){ 116 scanf("%d%d",&a,&b); 117 Add_edge(a,b); 118 Add_edge(b,a); 119 } 120 scanf("%d",&Q); 121 for(int i = 1; i <= Q; ++i){ 122 scanf("%d%d",&a,&b); 123 qa[i] = a,qb[i] = b; 124 Add_edge1(a,b,i); 125 Add_edge1(b,a,i); 126 } 127 Tarjan(1,0); 128 for(int i = 1; i <= Q; ++i){ 129 printf("%d\n",ans[i]); 130 } 131 return 0; 132 }