机房
数组链式前向星建图+堆优化版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;
}