HDU 6201 transaction transaction transaction (Dijstra, 2017 ACM/ICPC Asia Regional Shenyang Online)

Problem

给 n 个城市买卖书的价格 pricei (同城买卖同价)。n-1 条双向路将 n 个城市连通,每条路径给定 x y z ,表示 x 与 y 城市道路的长度为 z 。每前进 1 km 的代价为 1 。求从一个城市买 1 本书再带到另一个城市卖出的最大收益。

Idea

多源最短路加超级源点 转化为 单源最短路。貌似这种题队友总喜欢拿网络流去套… 233.

从超级源点向每个城市 i 连一条边权为 pricei 的边,跑一发 Dijstra 可以得到每个城市的最短路(将其视作是拿一本书到达此地的最小费用,已包含买书及路程的费用)。

遍历 n 个点,将最短路与 pricei (此是视作卖书价格)作差求最大收益。

Code

#include<bits/stdc++.h>
using namespace std;
const int N = 100000 + 10;
int T, n, pi[N];
long long dis[N];
struct Edge {
    int nxt, to, val;
} e[N*2];
int head[N], cnt;
void addedge(int u, int v, int w) {
    e[++cnt].nxt = head[u];
    e[cnt].to = v;
    e[cnt].val = w;
    head[u] = cnt;
}

struct Node {
    int idx;
    long long dist;
} p, q;

bool operator<(Node a, Node b) {
    return a.dist > b.dist;
}

void dijstra() 
{
    priority_queue<Node> que;
    for(int i=1;i<=n;i++)
    {
        p.idx = i;
        p.dist = pi[i];
        que.push(p);
        dis[i] = pi[i];
    }   

    while(!que.empty())
    {
        p = que.top();
        que.pop();
        if(dis[p.idx] < p.dist) continue;
        for(int i=head[p.idx];i;i=e[i].nxt)
        {
            q.idx = e[i].to;
            q.dist = p.dist + e[i].val;
            if(dis[q.idx] < q.dist) continue;
            dis[q.idx] = q.dist;
            que.push(q);
        }
    }
}
int main()
{
    scanf("%d", &T);
    while(T-- && scanf("%d", &n)!=EOF)
    {
        cnt = 0;
        memset(head, 0, sizeof(head));
        for(int i=1;i<=n;i++)
            scanf("%d", &pi[i]);
        for(int i=1, u, v, w;i<n;i++)
        {
            scanf("%d %d %d", &u, &v, &w);
            addedge(u, v, w);
            addedge(v, u, w);
        }

        dijstra();

        long long ans = 0;
        for(int i=1;i<=n;i++)
            ans = max(ans, pi[i] - dis[i]);
        printf("%lld\n", ans);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值