机房
数组链式前向星建图+堆优化版dijkstra
#include<iostream>
#include<queue>
#include<cstring>
#include<vector>
using namespace std;
typedef pair<int,int> pii;
//无向图开两倍
int e[200005],ne[200005],v[200005],h[200005],du[100005],idx;
int dist[100005],st[100005];
vector<pair<int,int>> ve;
//利用数组链式前向星建图
void add(int x,int y,int d)
{
e[++idx]=y;
ne[idx]=h[x];
//v数组即把该点的度数转为从该点出的边的权值
v[idx]=d;
h[x]=idx;
}
void dijkstra(int x,int y)
{
memset(st,0,sizeof(st));
memset(dist,0x3f,sizeof(dist));
dist[x]=0;
//用最小堆优化
priority_queue<pii,vector<pii>,greater<pii>> q;
q.push({0,x});
while(!q.empty())
{
int u=q.top().first,vv=q.top().second;
q.pop();
//即已经找到x到y的最小距离
if(vv==y) return;
//即该点已经被中转过了
if(st[vv]) continue;
st[vv]=1;
for(int i=h[vv];i!=0;i=ne[i])
{
int node=e[i];
if(dist[node]>dist[vv]+v[i])
{
dist[node]=dist[vv]+v[i];
q.push({dist[node],node});
}
}
}
}
int main()
{
int n,m;
cin>>n>>m;
for(int i=0;i<n-1;i++)
{
int x,y;
cin>>x>>y;
ve.push_back({x,y});
du[x]++;
du[y]++;
}
for(int i=0;i<n-1;i++)
{
int x=ve[i].first;
int y=ve[i].second;
add(x,y,du[x]);
add(y,x,du[y]);
}
for(int i=0;i<m;i++)
{
int u,v;
cin>>u>>v;
dijkstra(u,v);
//最后要加上终点的权值
cout<<dist[v]+du[v]<<endl;
}
return 0;
}