貼出來加上註釋方便查看複習,以後會更新總結
題目鏈接 點擊打開鏈接
代碼註釋:
用普通的最短路方法會超時 n到40000
<strong><span style="font-size:18px;color:#ff6600;">#include<iostream>
#include<cstring>
using namespace std;
#define N 40005
struct node
{
int u,v,w,next;
}a[2*N]; //無向圖結點需2*N
int head[N],dis[N],visit[N],pre[N],rank[N],use[N];//head[]中存的是從同一個點出發的多條邊的編號
int k;
void init()
{
k=0;
memset(head,-1,sizeof(head));
}
void add(int u,int v,int w)
{
a[k].u=u;
a[k].v=v;
a[k].w=w;
a[k].next=head[u];
head[u]=k++; //可以由next訪問到同一個點出發的其他邊的編號
}
void dfs(int u)
{
use[u]=1;
for(int i=head[u];i!=-1;i=a[i].next)
{
int v=a[i].v;
if(!use[v])
{
dis[v]=dis[u]+a[i].w;
rank[v]=rank[u]+1;
pre[v]=u;
dfs(v);
}
}
}
int lca(int u,int v)
{
if(u==v)
return u;
if(rank[u]>rank[v])
return lca(pre[u],v);
else
return lca(u,pre[v]);
}
int main()
{
int T,n,m,i;
cin>>T;
while(T--)
{
cin>>n>>m;
init();
int u,v,w;
for(i=1;i<n;i++)
{
cin>>u>>v>>w;
add(u,v,w);
add(v,u,w);
}
memset(dis,0,sizeof(dis));
memset(pre,0,sizeof(pre));
memset(use,0,sizeof(use));
memset(rank,0,sizeof(rank));
dfs(1);
while(m--)
{
cin>>u>>v;
cout<<dis[u]+dis[v]-2*dis[lca(u,v)]<<endl;
}
}
}
</span></strong>