hdu 6201 深度优先搜索

本文介绍了一道关于商人如何在不同城市间买卖图书以获得最大利润的问题。商人需考虑各城市图书价格及城市间的旅行成本。

Problem Description
Kelukin is a businessman. Every day, he travels around cities to do some business. On August 17th, in memory of a great man, citizens will read a book named "the Man Who Changed China". Of course, Kelukin wouldn't miss this chance to make money, but he doesn't have this book. So he has to choose two city to buy and sell. 
As we know, the price of this book was different in each city. It is ai yuan in it city. Kelukin will take taxi, whose price is 1yuan per km and this fare cannot be ignored.
There are n1 roads connecting n cities. Kelukin can choose any city to start his travel. He want to know the maximum money he can get.
 

Input
The first line contains an integer T (1T10) , the number of test cases. 
For each test case:
first line contains an integer n (2n100000) means the number of cities;
second line contains n numbers, the ith number means the prices in ith city; (1Price10000) 
then follows n1 lines, each contains three numbers xy and z which means there exists a road between x and y, the distance is zkm (1z1000)
 

Output
For each test case, output a single number in a line: the maximum money he can get.
 

Sample Input
1 4 10 40 15 30 1 2 30 1 3 2 3 4 10
 

Sample Output
8



真的,要不是当时评测机被那帮交脚本做题的家伙搞炸了,这题肯定能在比赛时做出来。

注意:这题时间限制是2000ms!!!

说一下思路:

这题的意思就是:一个商人只能在一个城市内买书或买书,然后把所买的书卖到下一个城市,而且买和卖都只有一次,期间从一个城市到另一个城市的路径长度要当成路费,问这个买卖的最大利润是多少。

那么这道题就是要你求一个点的点权,与另一个点的点权与两点之间的权值(中间可能隔着几个点)的和,的差的最大值。

即是:

maxx = max(maxx, points[maps[u][i].v] - points[st] - maps[u][i].w - dis);
maxx = max(maxx, points[st] - points[maps[u][i].v] - maps[u][i].w - dis);

这里,maxx是指那个最大值,st 指 起点,maps[u][i].v 指 终点,u 指终点的前一个点,i 指 u 点连接点的个数,maps[u][i].w 指 u 到 v 的边的权值,dis 指 起点到 u 点 的所有边的权值和,points 数组就是记录所有点的权值

maps在这里是vector,其声明为:

struct node
{
    LL v, w;
};
vector<node>maps[maxn];

要是vector不会的话百度一下吧



最后附上代码:


#include <cstdio>
#include <cstring>
#include <cmath>
#include <vector>
#include <algorithm>
using namespace std;
typedef long long LL;
///o(っ。Д。)っ AC万岁!!!!!!!!!!!!!!
const int maxn = 100090;
const int inf = -999999999;
struct node
{
    int v, w;
};
vector<node>maps[maxn];
int points[maxn] = {}, maxx;
void dfs(int st, int u, int uv, int dis)
{
    for(int i = 0; i < maps[u].size(); i++)
    {
        if(maps[u][i].v == st || maps[u][i].v == uv) continue;
        maxx = max(maxx, points[maps[u][i].v] - points[st] - maps[u][i].w - dis);
        maxx = max(maxx, points[st] - points[maps[u][i].v] - maps[u][i].w - dis);
        dfs(st, maps[u][i].v, u, dis + maps[u][i].w);
    }
}
int main()
{
    int _;
    scanf("%d", &_);
    while(_--)
    {
        int n;
        int u, v, w;
        scanf("%d", &n);
        struct node nn;
        for(int i = 1; i <= n; i++)
        {
            scanf("%d", &points[i]);
        }
        for(int i = 1; i < n; i++)
        {
            scanf("%d %d %d", &u, &v, &w);
            if(u > v)
            {
                swap(u, v);
            }
            nn.v = v;
            nn.w = w;
            maps[u].push_back(nn);
        }
        maxx = inf;
        for(int i = 1; i <= n; i++)
        {
            dfs(i, i, i, 0);
        }
        for(int i = 1; i <= n; i++)
        {
            maps[i].clear();
        }
        printf("%d\n", maxx);
    }
    return 0;
}
/*
4
30 40 10 40
1 3 20
1 2 40
1 4 10
*/


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值