hdu2586(LCA模板)
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=2586
还是要多练习,不够熟练。。
可以一看:http://blog.csdn.net/nameofcsdn/article/details/52230548
1 #include<cstdio> 2 #include<cstring> 3 #include<cmath> 4 #include<algorithm> 5 using namespace std; 6 7 const int maxn=40010; 8 9 int first[maxn<<1],node[maxn<<1],dep[maxn<<1],dp[maxn<<1][25]; 10 int dis[maxn]; 11 int head[maxn]; 12 int vis[maxn]; 13 int tot,cnt; 14 15 struct edge 16 { 17 int v,w,nex; 18 }e[maxn<<1]; 19 20 void add(int u,int v,int w) 21 { 22 e[cnt].v=v; 23 e[cnt].w=w; 24 e[cnt].nex=head[u]; 25 head[u]=cnt++; 26 } 27 int n,m; 28 int u,v,w; 29 void init() 30 { 31 for(int i=0;i<=n;i++) 32 { 33 head[i]=-1; 34 vis[i]=0; 35 } 36 cnt=tot=0; 37 } 38 void dfs(int u,int d,int w) 39 { 40 tot++; 41 vis[u]=1; 42 first[u]=tot; 43 node[tot]=u; 44 dep[tot]=d; 45 for(int i=head[u];i!=-1;i=e[i].nex) if(!vis[e[i].v]) 46 { 47 dis[e[i].v]=w+e[i].w; 48 dfs(e[i].v,d+1,dis[e[i].v]); 49 tot++; 50 node[tot]=u; 51 dep[tot]=d; 52 } 53 54 } 55 void RMQ_INIT(int n) 56 { 57 int k=log2(n); 58 for(int i=1;i<=n;i++) 59 dp[i][0]=i; 60 for(int j=1;j<=k;j++) 61 for(int i=1;i+(1<<j)-1<=n;i++) 62 { 63 int a=dp[i][j-1]; 64 int b=dp[i+(1<<j-1)][j-1]; 65 if(dep[a]<dep[b]) dp[i][j]=a; 66 else dp[i][j]=b; 67 } 68 } 69 int rmq(int x,int y) 70 { 71 int k=log2(y-x+1); 72 int a=dp[x][k]; 73 int b=dp[y-(1<<k)+1][k]; 74 if(dep[a]<dep[b]) return a; 75 return b; 76 } 77 78 int lca(int a,int b) 79 { 80 int x=first[a]; 81 int y=first[b]; 82 int k; 83 if(x>y) swap(x,y); 84 k=rmq(x,y); 85 return node[k]; 86 } 87 int main() 88 { 89 int t; 90 scanf("%d",&t); 91 while(t--) 92 { 93 scanf("%d%d",&n,&m); 94 init(); 95 for(int i=1;i<n;i++) 96 { 97 scanf("%d%d%d",&u,&v,&w); 98 add(u,v,w); 99 add(v,u,w); 100 } 101 102 dfs(1,1,0); //任意一点当作根即可 103 RMQ_INIT(tot); 104 while(m--) 105 { 106 scanf("%d%d",&u,&v); 107 printf("%d\n",dis[u]+dis[v]-2*dis[lca(u,v)]); 108 } 109 } 110 }