给出一棵树,对于每一个询问,给出2个节点,输出2个节点的距离。
输入中有字母,那个是没有用的,不用管。
思路:
0.选择编号为1的节点作为树的root
(注意:有些题的边是单向的,这时候我们要根据节点的入度来确定root,
双向的话一般可以随意选择一个节点作为root)
1.dfs1,求出dep和pa[i][0]
2.初始化数组pa
3.节点(u,v)的权值为w
把本来是边的权值w赋给u,v中dep较大的节点,
cost[i]表示节点i的权值为cost[i]
先初始化:cost[root]=0
4.dfs2,求每一个节点到root的距离dis[i]
5.查询:dis(u,v)=dis[u]+dis[v]-2*dis[lca(u,v)];
1 #include<cstdio> 2 #include<cstring> 3 4 using namespace std; 5 6 const int maxn=40000+5; 7 const int inf=0x3f3f3f3f; 8 9 inline int swap(int &x,int &y) 10 { 11 x^=y; 12 y^=x; 13 x^=y; 14 } 15 16 struct Edge 17 { 18 int to,next; 19 }; 20 Edge edge[maxn<<1]; 21 int head[maxn]; 22 int tot=0; 23 int cost[maxn]; 24 int dis[maxn]; 25 int pa[maxn][17]; 26 int dep[maxn]; 27 int e[maxn][3]; 28 29 void init() 30 { 31 memset(head,-1,sizeof head); 32 tot=1; 33 memset(dep,0,sizeof dep); 34 memset(pa,-1,sizeof pa); 35 } 36 37 void addedge(int u,int v) 38 { 39 edge[tot].to=v; 40 edge[tot].next=head[u]; 41 head[u]=tot++; 42 } 43 44 void dfs1(int u) 45 { 46 for(int i=head[u];~i;i=edge[i].next) 47 { 48 int v=edge[i].to; 49 if(!dep[v]) 50 { 51 dep[v]=dep[u]+1; 52 pa[v][0]=u; 53 dfs1(v); 54 } 55 } 56 } 57 58 void init_pa(int n) 59 { 60 for(int j=1;(1<<j)<=n;j++) 61 { 62 for(int i=1;i<=n;i++) 63 { 64 if(pa[i][j-1]!=-1) 65 pa[i][j]=pa[pa[i][j-1]][j-1]; 66 } 67 } 68 } 69 70 void dfs2(int u,int pre) 71 { 72 for(int i=head[u];~i;i=edge[i].next) 73 { 74 int v=edge[i].to; 75 if(v==pre) 76 continue; 77 dis[v]=dis[u]+cost[v]; 78 dfs2(v,u); 79 } 80 } 81 82 int query(int a,int b,int n) 83 { 84 int init_a=a; 85 int init_b=b; 86 if(dep[a]<dep[b]) 87 swap(a,b); 88 int cnt; 89 for(cnt=0;dep[a]-(1<<cnt)>=0;cnt++) 90 ; 91 cnt--; 92 for(int j=cnt;j>=0;j--) 93 { 94 if(dep[a]-(1<<j)>=dep[b]) 95 a=pa[a][j]; 96 } 97 if(a==b) 98 return dis[init_a]+dis[init_b]-2*dis[a]; 99 for(int i=cnt;i>=0;i--) 100 { 101 if(pa[a][i]!=-1&&pa[a][i]!=pa[b][i]) 102 { 103 a=pa[a][i]; 104 b=pa[b][i]; 105 } 106 } 107 return dis[init_a]+dis[init_b]-2*dis[pa[a][0]]; 108 } 109 110 void solve(int n) 111 { 112 dep[1]=1; 113 dfs1(1); 114 init_pa(n); 115 cost[1]=0; 116 dis[1]=0; 117 for(int i=1;i<=n;i++) 118 { 119 if(dep[e[i][0]]>dep[e[i][1]]) 120 swap(e[i][0],e[i][1]); 121 cost[e[i][1]]=e[i][2]; 122 } 123 dfs2(1,-1); 124 125 int m; 126 scanf("%d",&m); 127 for(int i=1;i<=m;i++) 128 { 129 int u,v; 130 scanf("%d%d",&u,&v); 131 printf("%d ",query(u,v,n)); 132 } 133 return ; 134 } 135 136 int main() 137 { 138 int n; 139 while(~scanf("%d",&n)) 140 { 141 init(); 142 int m; 143 scanf("%d",&m); 144 for(int i=1;i<=m;i++) 145 { 146 int u,v,w; 147 char ch; 148 scanf("%d %d %d %c",&e[i][0],&e[i][1],&e[i][2],&ch); 149 addedge(e[i][0],e[i][1]); 150 addedge(e[i][1],e[i][0]); 151 } 152 solve(n); 153 } 154 return 0; 155 }