BZOJ 1179 APIO 2009 Atm Tarjan+SPFA

本文介绍了一种解决有向图中从起点到终点经过各节点收集最大权值问题的方法。通过Tarjan算法进行强连通分量压缩,转换为拓扑图,并使用SPFA算法求解最短路径问题,最终实现高效的最大权值收集。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目大意:给出一张有向图,每一个节点有一个权值,经过一次之后会取走节点上的权值。有一个原点,多个汇点,问最多能收获多少权值。


思路:做一次Tarjan将图变成拓扑图,然后直接跑SPFA+Heap,比较慢,但是用了高大上的namespace,很开心。


CODE:

#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAX 500000
using namespace std;
 
struct Complex{
    int pos,len;
     
    Complex(int _,int __):pos(_),len(__) {}
    bool operator <(const Complex &a)const {
        return len < a.len;
    }
};
 
int points,edges,cnt;
int head[MAX],total;
int next[MAX],aim[MAX];
int src[MAX];
int S,T;
 
int deep[MAX],low[MAX],_total;
bool v[MAX];
int changed[MAX],sum[MAX],scc;
int stack[MAX],top;
bool in_stack[MAX];
 
namespace SPA{
    int head[MAX],total;
    int next[MAX],aim[MAX];
     
    int f[MAX];
     
    inline void Add(int x,int y)
    {
        next[++total] = head[x];
        aim[total] = y;
        head[x] = total;
    }
     
    int SPFA(int st,int ed)
    {
        static priority_queue<Complex> q;
        q.push(Complex(st,sum[st]));
        f[st] = sum[st];
        while(!q.empty()) {
            Complex temp = q.top(); q.pop();
            int x = temp.pos;
            if(f[x] > temp.len)  continue;
            for(int i = head[x]; i; i = next[i])
                if(f[aim[i]] < f[x] + sum[aim[i]]) {
                    f[aim[i]] = f[x] + sum[aim[i]];
                    q.push(Complex(aim[i],f[aim[i]]));
                }
        }
        return f[ed];
    }
}
 
inline void Add(int x,int y)
{
    next[++total] = head[x];
    aim[total] = y;
    head[x] = total;
}
 
void Tarjan(int x)
{
    deep[x] = low[x] = ++_total;
    v[x] = true;
    stack[++top] = x;
    in_stack[x] = true;
    for(int i = head[x]; i; i = next[i]) {
        if(!v[aim[i]])
            Tarjan(aim[i]),low[x] = min(low[x],low[aim[i]]);
        else if(in_stack[aim[i]])
            low[x] = min(low[x],deep[aim[i]]);
    }
    if(low[x] == deep[x]) {
        ++scc;
        int temp;
        do {
            temp = stack[top--];
            in_stack[temp] = false;
            sum[scc] += src[temp];
            changed[temp] = scc;
        }while(temp != x);
    }
}
 
int main()
{
    cin >> points >> edges;
    for(int x,y,i = 1; i <= edges; ++i) {
        scanf("%d%d",&x,&y);
        Add(x,y);
    }
    for(int i = 1; i <= points; ++i)
        scanf("%d",&src[i]);
    for(int i = 1; i <= points; ++i)
        if(!v[i])
            Tarjan(i);
    for(int x = 1; x <= points; ++x)
        for(int i = head[x]; i; i = next[i])
            if(changed[x] != changed[aim[i]])
                SPA::Add(changed[x],changed[aim[i]]);   
    cin >> S >> cnt;
    for(int x,i = 1; i <= cnt; ++i) {
        scanf("%d",&x);
        SPA::Add(changed[x],scc + 1);
    }
    cout << SPA::SPFA(changed[S],scc + 1) << endl;
    return 0;
}


内容概要:本文介绍了奕斯伟科技集团基于RISC-V架构开发的EAM2011芯片及其应用研究。EAM2011是一款高性能实时控制芯片,支持160MHz主频和AI算法,符合汽车电子AEC-Q100 Grade 2和ASIL-B安全标准。文章详细描述了芯片的关键特性、配套软件开发套件(SDK)和集成开发环境(IDE),以及基于该芯片的ESWINEBP3901开发板的硬件资源和接口配置。文中提供了详细的代码示例,涵盖时钟配置、GPIO控制、ADC采样、CAN通信、PWM输出及RTOS任务创建等功能实现。此外,还介绍了硬件申领流程、技术资料获取渠道及开发建议,帮助开发者高效启动基于EAM2011芯片的开发工作。 适合人群:具备嵌入式系统开发经验的研发人员,特别是对RISC-V架构感兴趣的工程师和技术爱好者。 使用场景及目标:①了解EAM2011芯片的特性和应用场景,如智能汽车、智能家居和工业控制;②掌握基于EAM2011芯片的开发板和芯片的硬件资源和接口配置;③学习如何实现基本的外设驱动,如GPIO、ADC、CAN、PWM等;④通过RTOS任务创建示例,理解多任务处理和实时系统的实现。 其他说明:开发者可以根据实际需求扩展这些基础功能。建议优先掌握《EAM2011参考手册》中的关键外设寄存器配置方法,这对底层驱动开发至关重要。同时,注意硬件申领的时效性和替代方案,确保开发工作的顺利进行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值