拓扑图学习指南

前置芝士

拓扑算法经常结合于其他高级算法,注重培养拓扑的核心思想,解决实际问题。

拓扑排序

拓扑排序是一种在有向无环图(DAG)中对节点进行排序的算法,其中每个节点表示一个任务或活动,并且边表示任务之间的依赖关系。

在拓扑排序中,排在前面的节点不依赖于排在后面的节点,因此可以按照一定的顺序依次执行这些任务或活动。

Kahn算法(卡恩)

时间复杂度:O(N+M)

[算法流程]

  • 初始化一个队列(FIFO)和一个存储结果的列表。
  • 统计每个节点的入度(即节点有多少个前驱节点),并将入度为0的节点加入队列。
  • 当队列非空时,执行以下步骤:
    a. 从队列中取出一个节点。
    b. 将该节点添加到结果列表。
    c. 遍历该节点的所有邻居节点:
    • 将邻居节点的入度减1。
    • 若邻居节点的入度为0,将其加入队列。
  • 遍历结束后,如果结果列表的长度等于图中节点的个数,则拓扑排序成功;否则,图中存在环,无法进行拓扑排序。
  • 求字典序最小的拓扑序,将Kahn算法中的队列转为优先队列(小根堆)

最长路

[problem description]

G 为有 n 个顶点的带权有向无环图,G 中各顶点的编号为 1n,请设计算法,计算图 G1,n 间的最长路径。

[input]

输入的第一行有两个整数,分别代表图的点数 n 和边数 m

2 到第 (m+1) 行,每行 3 个整数 u,v,wu<v),代表存在一条从 uv 边权为 w 的边。

[output]

输出一行一个整数,代表 1n 的最长路。

1 无法到达 n,请输出 1

1n15000m5×1041u,vn105w105

[solved]

int n,m;
const int N=1510;
vector<int> e[N],d[N];
int w[N],din[N],f[N];
queue<int> q;
void solve(){
	cin>>n>>m;
    for(int i=1;i<=m;i++){
        int x,y,w;
        cin>>x>>y>>w;
        e[x].push_back(y);
        d[x].push_back(w);
        din[y]++;
    }
    for(int i=2;i<=n;i++){
        f[i]=-1e9;
        if(!din[i]) q.push(i);
    }
    while(!q.empty()){
        int x=q.front();
        q.pop();
        for(int i=0;i<e[x].size();i++){
            if(!--din[e[x][i]]) q.push(e[x][i]);
        }
    }
    q.push(1);
    while(!q.empty()){
        int x=q.front();
        q.pop();
        for(int i=0;i<e[x].size();i++){
            int v=e[x][i];
            if(f[v]<f[x]+d[x][i]) f[v]=f[x]+d[x][i];
            if(!--din[v]) q.push(v);
        }
    }
    if(f[n]==-1e9) cout<<"-1";
    else cout<<f[n];
}
posted @   White_Sheep  阅读(45)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示