[luogu2469] 星际竞速

题面

​ 巨佬一眼就能看出这是最小路径覆盖, 我这个蒟蒻还是太弱了...

​ 我们可以知道跳跃值为点权w[i], 两点之间距离为边权ww

​ 对于每个点, 在最小路径覆盖问题中, 假设每个点都是一条路径, 即每个点都由能力爆发得到, 那么最初的答案便是\(ans\) = \(\sum_{ i = 1}^{n}\), 对于每一条连接u和v的边, 可以看做不使用能力爆发而从u往v走, 那么我们就减少了点v的点权, 加上了这一条边的代价, 即从\(min(u, v)\)\(max(u, v)\)连一条容量为1, 费用为\(ww - w[v]\), 那么只要每次增广找到一条费用为负的边就可以减少总时间, 即当\(d[T]\)小于0时就可以将\(ans += d[T]\), 所以, 只要当此次增广无法到达T或者\(d[T]\) > 0时就可以return 0了.

具体代码

#include <iostream>
#include <cstring>
#include <cstdio>
#include <queue>
#define N 5005
using namespace std;

int n, m, S, T, head[N], cnt = 1, p[N], vis[N], w[N];
struct node
{
    int from, to, next;
    long long flow, cost; 
} edge[100005];
long long a[N], d[N], ans; 

inline int read()
{
    int x = 0, w = 1;
    char c = getchar();
    while(c < '0' || c > '9') { if (c == '-') w = -1; c = getchar(); }
    while(c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); }
    return x * w;
}

inline void add(int u, int v, int w, int cost)
{
    edge[++cnt] = { u, v, head[u], w, cost }; head[u] = cnt;
    edge[++cnt] = { v, u, head[v], 0, -cost }; head[v] = cnt; 
}

bool SPFA()
{
    memset(d, 0x3f, sizeof(d)); memset(a, 0x3f, sizeof(a));
    queue<int> q; q.push(S); d[S] = 0;
    while(!q.empty())
    {
        int u = q.front(); q.pop(); vis[u] = 0; 
        for(int i = head[u]; i; i = edge[i].next)
        {
            int v = edge[i].to;
            if(d[v] > d[u] + edge[i].cost && edge[i].flow > 0)
            {
                d[v] = d[u] + edge[i].cost; a[v] = min(a[u], edge[i].flow);
                p[v] = i; if(!vis[v]) { vis[v] = 1; q.push(v); }
            }
        }
    }
    if(d[T] == d[0] || d[T] > 0) return 0;
    if(d[T] < 0) ans += (d[T] * a[T]);
    for(int i = T; i != S; i = edge[p[i]].from)
    {
        edge[p[i]].flow -= a[T]; edge[p[i] ^ 1].flow += a[T]; 
    }
    return 1; 
}

int main()
{
    n = read(); m = read(); S = 2 * n + 1; T = S + 1; 
    for(int i = 1; i <= n; i++) { w[i] = read(); ans += w[i]; add(S, i, 1, 0); }
    for(int i = 1; i <= n; i++) add(i + n, T, 1, 0);
    for(int i = 1; i <= m; i++)
    {
        int u = read(), v = read(), ww = read();
        if(u > v) swap(u, v);
        add(u, v + n, 1, ww - w[v]); 
    }
    while(SPFA());
    printf("%lld\n", ans); 
    return 0;
}

转载于:https://www.cnblogs.com/ztlztl/p/10568317.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
SQLAlchemy 是一个 SQL 工具包和对象关系映射(ORM)库,用于 Python 编程语言。它提供了一个高级的 SQL 工具和对象关系映射工具,允许开发者以 Python 类和对象的形式操作数据库,而无需编写大量的 SQL 语句。SQLAlchemy 建立在 DBAPI 之上,支持多种数据库后端,如 SQLite, MySQL, PostgreSQL 等。 SQLAlchemy 的核心功能: 对象关系映射(ORM): SQLAlchemy 允许开发者使用 Python 类来表示数据库表,使用类的实例表示表中的行。 开发者可以定义类之间的关系(如一对多、多对多),SQLAlchemy 会自动处理这些关系在数据库中的映射。 通过 ORM,开发者可以像操作 Python 对象一样操作数据库,这大大简化了数据库操作的复杂性。 表达式语言: SQLAlchemy 提供了一个丰富的 SQL 表达式语言,允许开发者以 Python 表达式的方式编写复杂的 SQL 查询。 表达式语言提供了对 SQL 语句的灵活控制,同时保持了代码的可读性和可维护性。 数据库引擎和连接池: SQLAlchemy 支持多种数据库后端,并且为每种后端提供了对应的数据库引擎。 它还提供了连接池管理功能,以优化数据库连接的创建、使用和释放。 会话管理: SQLAlchemy 使用会话(Session)来管理对象的持久化状态。 会话提供了一个工作单元(unit of work)和身份映射(identity map)的概念,使得对象的状态管理和查询更加高效。 事件系统: SQLAlchemy 提供了一个事件系统,允许开发者在 ORM 的各个生命周期阶段插入自定义的钩子函数。 这使得开发者可以在对象加载、修改、删除等操作时执行额外的逻辑。
SQLAlchemy 是一个 SQL 工具包和对象关系映射(ORM)库,用于 Python 编程语言。它提供了一个高级的 SQL 工具和对象关系映射工具,允许开发者以 Python 类和对象的形式操作数据库,而无需编写大量的 SQL 语句。SQLAlchemy 建立在 DBAPI 之上,支持多种数据库后端,如 SQLite, MySQL, PostgreSQL 等。 SQLAlchemy 的核心功能: 对象关系映射(ORM): SQLAlchemy 允许开发者使用 Python 类来表示数据库表,使用类的实例表示表中的行。 开发者可以定义类之间的关系(如一对多、多对多),SQLAlchemy 会自动处理这些关系在数据库中的映射。 通过 ORM,开发者可以像操作 Python 对象一样操作数据库,这大大简化了数据库操作的复杂性。 表达式语言: SQLAlchemy 提供了一个丰富的 SQL 表达式语言,允许开发者以 Python 表达式的方式编写复杂的 SQL 查询。 表达式语言提供了对 SQL 语句的灵活控制,同时保持了代码的可读性和可维护性。 数据库引擎和连接池: SQLAlchemy 支持多种数据库后端,并且为每种后端提供了对应的数据库引擎。 它还提供了连接池管理功能,以优化数据库连接的创建、使用和释放。 会话管理: SQLAlchemy 使用会话(Session)来管理对象的持久化状态。 会话提供了一个工作单元(unit of work)和身份映射(identity map)的概念,使得对象的状态管理和查询更加高效。 事件系统: SQLAlchemy 提供了一个事件系统,允许开发者在 ORM 的各个生命周期阶段插入自定义的钩子函数。 这使得开发者可以在对象加载、修改、删除等操作时执行额外的逻辑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值