HDU 6201 transaction transaction transaction(拆点最长路)

transaction transaction transaction

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 132768/132768 K (Java/Others)
Total Submission(s): 88    Accepted Submission(s): 39

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 n−1 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 (1≤T≤10) , the number of test cases.
For each test case:
first line contains an integer n (2≤n≤100000) means the number of cities;
second line contains n numbers, the ith number means the prices in ith city; (1≤Price≤10000)
then follows n−1 lines, each contains three numbers x, y and z which means there exists a road between x and y, the distance is zkm (1≤z≤1000).

(1≤z≤1000).

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

题目链接:HDU 6201

这题感觉还是蛮有意思的,由于以前被拆点的题目坑过,看到这题就是求位置起点的最长路,但是他有边权,也有点权啊怎么办,可以把点拆成入点和出点,然后构造源点S和终点T,然后这样连边(由于我用最长路求,显然记买入和路费为负,卖出为正):

$<i,i+n,0>$,自身拆点肯定要连;

$<u+n,v,-dis>$、$<v+n,u,-dis>$,由于要求价值最大,花费显然要负权;

$<S,i,-price[i]>$,由于位置起点,那么直接把点都连到S上从S开始,并且这样刚好可以把点权转换成边权

$<i+n,T,price[i]>$,卖掉第i个后到T点。

然后这样写了之后感觉没什么问题就交了,反正是1A了。

代码:

#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <cstdlib>
#include <cstring>
#include <bitset>
#include <string>
#include <stack>
#include <cmath>
#include <queue>
#include <set>
#include <map>
using namespace std;
#define INF 0x3f3f3f3f
#define LC(x) (x<<1)
#define RC(x) ((x<<1)+1)
#define MID(x,y) ((x+y)>>1)
#define fin(name) freopen(name,"r",stdin)
#define fout(name) freopen(name,"w",stdout)
#define CLR(arr,val) memset(arr,val,sizeof(arr))
#define FAST_IO ios::sync_with_stdio(false);cin.tie(0);
typedef pair<int, int> pii;
typedef long long LL;
const double PI = acos(-1.0);
const int N = 100010;
struct edge
{
    int to, nxt, d;
    edge() {}
    edge(int _to, int _nxt, int _d): to(_to), nxt(_nxt), d(_d) {}
} E[N * 5];
int head[N << 1], tot;
bitset < N << 1 > vis;
int d[N << 1];
int price[N];

void init()
{
    CLR(head, -1);
    tot = 0;
}
inline void add(int s, int t, int d)
{
    E[tot] = edge(t, head[s], d);
    head[s] = tot++;
}
void spfa(int s)
{
    CLR(d, -INF);
    vis.reset();
    vis[s] = 1;
    d[s] = 0;
    queue<int>Q;
    Q.push(s);
    while (!Q.empty())
    {
        int u = Q.front();
        Q.pop();
        vis[u] = 0;
        for (int i = head[u]; ~i; i = E[i].nxt)
        {
            int v = E[i].to;
            if (d[v] < d[u] + E[i].d)
            {
                d[v] = d[u] + E[i].d;
                if (!vis[v])
                {
                    vis[v] = 1;
                    Q.push(v);
                }
            }
        }
    }
}
int main(void)
{
    int T, n, a, b, dx, i;
    scanf("%d", &T);
    while (T--)
    {
        init();
        scanf("%d", &n);
        int S = 0, T = 2 * n + 1;
        for (i = 1; i <= n; ++i)
        {
            scanf("%d", &price[i]);
            add(i, i + n, 0);
            add(S, i, -price[i]);
            add(i + n, T, price[i]);
        }
        for (i = 1; i < n; ++i)
        {
            scanf("%d%d%d", &a, &b, &dx);
            add(a + n, b, -dx);
            add(b + n, a, -dx);
        }
        spfa(S);
        printf("%d\n", d[T]);
    }
    return 0;
}
时间: 2024-10-14 07:11:42

HDU 6201 transaction transaction transaction(拆点最长路)的相关文章

HDU 2196 Computer(树形DP求最长路)

Problem Description A school bought the first computer some time ago(so this computer's id is 1). During the recent years the school bought N-1 new computers. Each new computer was connected to one of settled earlier. Managers of school are anxious a

Spring事务嵌套抛异常org.springframework.transaction.UnexpectedRollbackException: Transaction rolled back because it has been marked as rollback-only

在业务接口中,一个方法嵌套了另外一个方法,2个方法上都加了@Transactional事务注解. 业务接口: @Service public class TransactionalTestServiceImpl implements TransactionalTestService { @Autowired private TransactionalTestHandle transactionalTestHandle; @Override @Transactional public void f

HDU 6201 2017沈阳网络赛 树形DP或者SPFA最长路

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6201 题意:给出一棵树,每个点有一个权值,代表商品的售价,树上每一条边上也有一个权值,代表从这条边经过所需要的花费.现在需要你在树上选择两个点,一个作为买入商品的点,一个作为卖出商品的点,当然需要考虑从买入点到卖出点经过边的花费.使得收益最大.允许买入点和卖出点重合,即收益最小值为0. 解法:我们设1为根节点,假设一开始一个人身上的钱为0.我们设dp[i][0]表示从根节点走到i及其子树并中任一点买

POJ 3422 HDU 2686,3376 费用流拆点建图

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3376 http://acm.hdu.edu.cn/showproblem.php?pid=2686 http://poj.org/problem?id=3422 POJ 3422为从矩阵左上角走到右下角,最多走k次,每个格子里的数字只能算一次,后面可以重复经过,求经过的各个数字的和的最大值. 拆点,入点向出点连流量为1,费用为当前格子负值的边,向下方,右方连边,流量为k,费用为0,起点连流量为1,

HDU 3277 Marriage Match III(拆点+二分+最大流SAP)

这个题目是说,有n个女的和男的找伴侣.然后女的具有主动选择权,每个女的可以选自己喜欢的男的,也可以挑选k个不喜欢的男的,做法就是:把女的拆点,u1->u2建立一条容量为k的边.如果遇见喜欢的男生i->j+2*n建一条容量为1的边,否则i+n->j+2*n建一条容量为1的边.最后将源点和女生相连容量为mid,汇点与男生相连容量为mid.枚举mid,看是否会产生满流. 可能姿势不够优美dinic超时了啊,换成SAP快了很多啊... Marriage Match III Time Limit:

HDU 2732 Leapin&#39; Lizards(拆点法+最大流)

该题是一道比较简单拆点+最大流的题目,因为每个柱子都有一定的寿命,很容易将其对应成流量,那么处理结点容量的一般方法当然是拆点法 .该题反而对边的容量没有要求,为保险起见可以设成无穷大.   该题的思路很好想,建议独立编写代码 . 推荐题目: 点击打开链接    结点法的一些见解 也可以看这里. 细节参见代码: #include<bits/stdc++.h> using namespace std; typedef long long ll; const int INF = 100000000;

HDU 4289 Control (最大流+拆点)

http://acm.hdu.edu.cn/showproblem.php?pid=4289 题目讲的是有一些恐怖分子要从S市去往D市,要求在一些城市中安排特工,保证一定能够抓住恐怖分子,因为安排特工需要一定的费用,所以希望找出最小的花费. 思路:可以把每个城市,即每个点拆分成进来的点和出去的点,如x点分成x和x+n,两点连接的边权值为x点上安排特工的费用.而如果x和y两点有连线,则连接x+n,y,然后求从S市到达D市的最大流.之所以能这样求,是因为在求最大流的过程中每次所更新的流量是所有边中最

hdu 4292 Food 最大流+拆点

Food Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2664    Accepted Submission(s): 899 Problem Description You, a part-time dining service worker in your college's dining hall, are now confus

HDU 3998 Sequence(经典问题,最长上升子序列)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3998 解题报告:求一个数列的最长上升子序列,并求像这样长的不相交的子序列最多有多少个. 我用的是最简单的方法,就是每次求最长上升子序列,然后每次将求得的子序列从数列里面删掉,然后再对剩下的数列求最长上升子序列,如果求得的子序列的长度比第一次求得的长度小的话,就退出.不过我这题卡了很久,原因就是因为用这种方法求的过程中,用到了很多变量,但是没有注意每一步求最长上升子序列的时候都要进行初始化,哎. Vi