【题解】bzoj2200 并查集+拓扑排序+dijkstra+bfs

针对bzoj2200问题,利用并查集确定图的连通块,将双向无负权边视为DAG,通过拓扑排序求单元最短路。每个连通块内部使用堆优化的Dijkstra算法。步骤包括:1.构建连通块并记录节点归属;2.统计连通块入度,入度为0的加入队列;3.运行Dijkstra并更新边的入度,入度为0的加入拓扑序队列。总时间复杂度为O(t+p+rlogt)。
摘要由CSDN通过智能技术生成

题目链接
由题意可以知道双向道路没有负边权,而单向负权路不构成环。如果把所有的道路单独添加到图里,会形成若干个连通块。把每个连通块看做一个点,把航线添加进图里,会形成DAG。可以在DAG上跑拓扑序,在线性时间里求出单元最短路。在每个连通块内部用堆优化的dijkstra。
步骤:
1.将所有道路添加到图中形成若干连通块,遍历每一个连通块记录每个节点所属的连通块编号(并查集);
2.将有向边添加到图中,统计每个连通块的总入度,将入度为0的连通块添加到队列中;
3.取出连通块跑dijkstra,扫描连通块内部外部的所有边,扫描到连通块外部的边入度减一,入度为0时插入拓扑序队列中;
最终最短路数组即为所求,时间复杂度O(t+p+rlogt);

#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
using namespace std;
#define _rep(i,a,b) for(int i=(a);i<=(b);i++)
#define _for(i,a,b) for(int i=(a);i<(b);i++)
#define PB(v) push_back(v)
#define INF 0x3f3f3f3f
const int N=25010;
const int M=5e4+10;
int t,r,p,s;
int fa[N];
struct Edge{
    int v,w,nx;
}edge[M<<2]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值