LCA
详细 百度百科。
例子hdu 2586
1 #pragma comment(linker, "/STACK:16777216") 2 #include <iostream> 3 #include <cstdio> 4 #include <cstring> 5 #include <vector> 6 7 using namespace std; 8 9 const int N=100001; 10 typedef pair<int,int> pii; 11 vector<pii>g[N]; 12 int fa[N]; 13 int check[N]; 14 int ancer[N]; 15 int dp[N]; 16 int ans[N]; 17 18 vector<pii>h[N]; 19 int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);} 20 21 void lca(int u,int f){ 22 int size=g[u].size(); 23 int v,id; 24 for(int i=0;i<size;i++)if(g[u][i].first!=f){ 25 v=g[u][i].first; 26 dp[v]=dp[u]+g[u][i].second; 27 lca(v,u); 28 fa[v]=u; 29 ancer[find(u)]=u; 30 } 31 check[u]=1; 32 size=h[u].size(); 33 for(int i=0;i<size;i++){ 34 v=h[u][i].first; 35 id=h[u][i].second; 36 if(check[v]){ 37 ans[id]=dp[u]+dp[v]-2*dp[ancer[find(v)]]; 38 } 39 } 40 } 41 void init(int n){ 42 for(int i=0;i<=n;i++)fa[i]=i; 43 memset(check,0,sizeof(int)*(n+1)); 44 for(int i=0;i<=n;i++){g[i].clear();h[i].clear();} 45 dp[1]=0; 46 } 47 int main() 48 { 49 int n,m; 50 int x,y,k; 51 int T; 52 cin>>T; 53 while(T--){ 54 scanf("%d%d",&n,&m); 55 init(n); 56 for(int i=1;i<n;i++){ 57 scanf("%d%d%d",&x,&y,&k); 58 g[x].push_back(make_pair(y,k)); 59 g[y].push_back(make_pair(x,k)); 60 } 61 for(int i=1;i<=m;i++){ 62 scanf("%d%d",&x,&y); 63 h[x].push_back(make_pair(y,i)); 64 h[y].push_back(make_pair(x,i)); 65 } 66 lca(1,-1); 67 for(int i=1;i<=m;i++){ 68 printf("%d\n",ans[i]); 69 } 70 } 71 72 return 0; 73 }
#pragma comment(linker, "/STACK:16777216") #include <iostream> #include <cstdio> #include <cstring> #include <vector> using namespace std; const int N=80000; const int M=20; int p[N][M]; int d[N]; int dis[N]; typedef pair<int,int> pii; vector <pii>g[N]; void build(int u,int fa){ p[u][0]=fa; d[u]=d[fa]+1; for(int i=1;i<M;i++){ p[u][i]=p[p[u][i-1]][i-1]; } int size=g[u].size(); for(int i=0;i<size;i++)if(g[u][i].first!=fa){ int v=g[u][i].first; dis[v]=dis[u]+g[u][i].second; build(v,u); } } int find(int a,int k){ for(int i=0;k;i++,k>>=1){ if(k&1)a=p[a][i]; } return a; } int lca(int a,int b){ if(d[a]>d[b]) swap(a,b); b=find(b,d[b]-d[a]); if(a!=b){ for(int j=M-1;j>=0;j--){ if(p[a][j]!=p[b][j]){ a=p[a][j],b=p[b][j]; } } a=p[a][0],b=p[b][0]; } return a; } void init(int n){ for(int i=0;i<=n;i++)g[i].clear(); memset(d,0,sizeof(d)); memset(dis,0,sizeof(dis)); } int main() { int T; cin>>T; int n,m; int u,v,w; while(T--){ scanf("%d%d",&n,&m);init(n); for(int i=1;i<n;i++){ scanf("%d%d%d",&u,&v,&w); g[u].push_back(make_pair(v,w)); g[v].push_back(make_pair(u,w)); } build(1,-1); for(int i=1;i<=m;i++){ scanf("%d%d",&u,&v); int cao=lca(u,v); printf("%d\n",dis[u]+dis[v]-2*dis[cao]); } //puts(""); } return 0; } 倍增法

浙公网安备 33010602011771号