最短路径树
最短路径树,即\(Shortest\) \(Path\) \(Tree\),对于一张无向图,固定一个源点,树上每个点到源点的最短距离都等于原图中该点到源点的最短距离。
最短路径树是所有路径树中边权和最小的。
通常使用\(dijkstra\)算法来找出\(SPT\),在每次松弛操作时,如果松弛成功,记该点的前驱边的编号,因为边时逐一加进堆中的,所以最后形成的是一棵SPT。
注意,松弛操作需要判断相等,相等时也算松弛成功。
假设两条路径到\(y\)的\(dis\)相等,分别有\(x_1->y\)和\(x_2->y\),若\(dis[x_1]<dis[x_2]\),可以知道\((x_1->y)>(x_2->y)\),同时在\(dijkstra\)中\(x_1\)先于\(x_2\)被扩展到,取后者\(x_2\)更优。
void dijkstra(int s){
priority_queue<pair<int,int>,vector<pair<int,int>>,greater<pair<int,int>>>q;
memset(dis,0x3f,sizeof(dis));
memset(vis,0,sizeof(vis));
dis[s]=0;
q.push({0,s});
while(!q.empty()){
int x=q.top().second;
q.pop();
if(vis[x])continue;
vis[x]=1;
for(int i=h[x];i;i=e[i].next){
int y=e[i].to;
if(dis[y]>=dis[x]+e[i].w){
dis[y]=dis[x]+e[i].w;
q.push({dis[y],y});
pre[y]=i;
}
}
}
}
给定无向图的源点,求边权和最小的最短路径树。
记录每个点的前驱边后,对前驱边的权值进行累加。
cin>>s;
dijkstra(s);
for(int i=1;i<=n;i++){
if(i==s)continue;
sum+=e[pre[i]].w;
}
cout<<sum<<'\n';
for(int i=1;i<=n;i++)if(i!=s)cout<<(pre[i]+1>>1)<<' ';
给定无向图,要求删边至最多剩余\(k\)条边,定义好点为最后\(1\)点到它的最短路长度仍然等于原图中的最短路长度的节点,最大化好点的个数。
将保留的边建成一棵树,即在原图中选出\(min(k,n-1)\)条边,在\(dijkstra\)后判断从\(1\)开始\(dfs\),判断每条边是否在\(SPT\)上并记录数量即可。
void dfs(int x){
for(int i=h[x];i;i=e[i].next){
int y=e[i].to;
if(i==pre[y]){
cout<<(i+1>>1)<<' ';
dfs(y);
}
}
}
给定无向图,选\(n-1\)条道路,使得\(1\)到所有城市的距离和最小,准备\(k\)个可能方案,若方案数少于\(k\)种则输出方案。
由于边权均为\(1\),可以使用\(bfs\)跑最短路,在每个点被松弛时,将该点的前驱边存入该点的集合,最后的方案数就是每个点集合大小的乘积。由于当\(dis[y]>dis[x]+1\)时,\(y\)一定是首次被扩展到,集合中没有元素,所以不需要清空集合。
inline void bfs(int s){
queue<int>q;
memset(dis,0x3f,sizeof(dis));
q.emplace(s);
dis[s]=0;
while(!q.empty()){
int x=q.front();
q.pop();
if(vis[x])continue;
vis[x]=1;
for(int i=h[x];i;i=e[i].next){
int y=e[i].to;
if(dis[y]>=dis[x]+1){
dis[y]=dis[x]+1;
v[y].emplace_back(i+1>>1);
q.emplace(y);
}
}
}
}
void dfs(int dep){
if(dep==n+1){
for(int i=1;i<=m;i++)cout<<vis[i];
if(++num>=k)exit(0);
cout<<'\n';
return;
}
for(auto x:v[dep]){
vis[x]=1;
dfs(dep+1);
vis[x]=0;
}
}
bfs(1);
int cnt=1;
for(int i=2;i<=n;i++){
if(cnt*v[i].size()>k){
cnt=k;
break;
}
else cnt*=v[i].size();
}
cout<<cnt<<'\n';
memset(vis,0,sizeof(vis));
dfs(2);

浙公网安备 33010602011771号