HDU 6201 transaction transaction transaction DFS 图论

  题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=6201

  题目描述: 有一棵节点的树, 每条边有权值, 可以任意选择起点和终点, 得到一个值 = 终点值 - 经过的边权值 - 起点值, 最大化这个值

  解题思路: 我们先要求得的值是每个节点有书的时候的最小花费, 由于此最小花费可能是本节点买书, 也有可能是儿子买书, 现在我们将从叶子节点开始向上遍历, 这样只会使得所有的父子节点互相更新, 可是这个时候兄弟节点还没有更新, 所以我们做第二遍DFS由父节点更新子节点

  代码:

#include <iostream>
#include <cstdio>
#include <string>
#include <vector>
#include <cstring>
#include <iterator>
#include <cmath>
#include <algorithm>
#include <stack>
#include <deque>
#include <map>
#include <set>
#include <queue>
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
#define mem0(a) memset(a,0,sizeof(a))
#define mem1(a) memset(a,-1,sizeof(a))
#define sca(x) scanf("%d",&x)
#define de printf("=======\n")
typedef long long ll;
using namespace std;

const int maxn = 1e5+100;
int v[maxn];
int vis[maxn];
int cost[maxn];
int ans;
vector<pair<int, int>> child[maxn];

void dfs1(int x) {
    vis[x] = 1;
    int len = (int)child[x].size();
    cost[x] = v[x];
    for( int i = 0; i < len; i++ ) {
        if( !vis[child[x][i].first] ) {
            dfs1(child[x][i].first);
            cost[x] = min( cost[x], cost[child[x][i].first]+child[x][i].second);
        }
    }
}

void dfs2(int x) {
    vis[x] = 1;
    int len = (int)child[x].size();
    for( int i = 0; i < len; i++ ) {
        if( !vis[child[x][i].first] ) {
            if( cost[x] + child[x][i].second < cost[child[x][i].first] ) {
                cost[child[x][i].first] = cost[x] + child[x][i].second;
                dfs2(child[x][i].first);
            }
        }
    }
    ans = max( ans, v[x]-cost[x] );
}
int main() {
    int t;
    scanf( "%d", &t );
    while( t-- ) {
        int n;
        scanf( "%d", &n );
        mem0(v);
        mem0(cost);
        for(int i = 1; i <= n; i++) {
            child[i].clear();
            vis[i] = 0;
        }
        for( int i = 1; i <= n; i++ ) {
            scanf( "%d", v+i );
        }

        for( int i = 1; i < n; i++ ) {
            int s, e, w;
            scanf( "%d%d%d", &s, &e, &w );
            child[s].push_back(pair<int, int>(e,w));
            child[e].push_back(pair<int, int>(s,w));
        }
        ans = 0 ;
        dfs1(1);
        mem0(vis);
        dfs2(1);
        printf( "%d\n", ans );
    }
    return 0;
}

  思考: 代码过不了, 现在已经十二点半了, 不改了, 睡了,通过这个意识到了自己树的薄弱, 以后要加强, 然后决定从现在开始就造轮子......搞一波儿事情了可以

时间: 2024-12-30 02:06:06

HDU 6201 transaction transaction transaction DFS 图论的相关文章

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

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 哈密顿绕行世界问题 (dfs)

Problem Description 一个规则的实心十二面体,它的 20个顶点标出世界著名的20个城市,你从一个城市出发经过每个城市刚好一次后回到出发的城市. Input 前20行的第i行有3个数,表示与第i个城市相邻的3个城市.第20行以后每行有1个数m,m<=20,m>=1.m=0退出. Output 输出从第m个城市出发经过每个城市1次又回到m的所有路线,如有多条路线,按字典序输出,每行1条路线.每行首先输出是第几条路线.然后个一个: 后列出经过的城市.参看Sample output

HDU 1241 Oil Deposits --- 入门DFS

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1241 /* HDU 1241 Oil Deposits --- 入门DFS */ #include <cstdio> int m, n; //n行m列 char mapp[105][105]; /* 将和i,j同处于一个连通块的字符标记出来 */ void dfs(int i, int j){ if (i < 0 || j < 0 || i >= n || j >= m

hdu 2489 Minimal Ratio Tree(dfs枚举 + 最小生成树)~~~

题目: 链接:点击打开链接 题意: 输入n个点,要求选m个点满足连接m个点的m-1条边权值和sum与点的权值和ans使得sum/ans最小,并输出所选的m个点,如果有多种情况就选第一个点最小的,如果第一个点也相同就选第二个点最小的........ 思路: 求一个图中的一颗子树,使得Sum(edge weight)/Sum(point weight)最小~ 数据量小,暴力枚举~~~~~dfs暴力枚举C(M,N)种情况. 枚举出这M个点之后,Sum(point weight)固定,进行prim或者K

HDU 1010 Tempter of Bone DFS + 奇偶剪枝

奇偶剪枝: 对于从起始点 s 到达 终点 e,走且只走 t 步的可达性问题的一种剪枝策略. 如下列矩阵 : 从任意 0 到达 任意 0,所需步数均为偶数,到达任意 1 ,均为奇数.反之亦然 所以有,若s走且只走 t 步可到达e,则必有t >= abs(s.x - e.x) + abs(s.y - e.y),且 (t&1) == ((abs(s.x - e.x) + abs(s.y - e.y))&1). 否则必不可达. #include <iostream> #inclu

HDU 1162 Eddy&#39;s picture(图论-最小生成树)

题目如下: Eddy's picture Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 7267    Accepted Submission(s): 3676 Problem Description Eddy begins to like painting pictures recently ,he is sure of himse

HDU 1501 Zipper(DP,DFS)

题意  判断能否由字符串a,b中的字符不改变各自的相对顺序组合得到字符串c 本题有两种解法  DP或者DFS 考虑DP  令d[i][j]表示能否有a的前i个字符和b的前j个字符组合得到c的前i+j个字符  值为0或者1  那么有d[i][j]=(d[i-1][j]&&a[i]==c[i+j])||(d[i][j-1]&&b[i]==c[i+j])   a,b的下标都是从1开始的  注意0的初始化 #include<cstdio> #include<cst

HDU 1180 诡异的楼梯 (DFS)

诡异的楼梯 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others) Total Submission(s): 6472    Accepted Submission(s): 1525 Problem Description Hogwarts正式开学以后,Harry发现在Hogwarts里,某些楼梯并不是静止不动的,相反,他们每隔一分钟就变动一次方向. 比如下面的例子里,一开始楼梯在竖

hdu 1241 Oil Deposits(DFS求连通块)

HDU 1241  Oil Deposits L -DFS Time Limit:1000MS     Memory Limit:10000KB     64bit IO Format:%I64d & %I64u Description The GeoSurvComp geologic survey company is responsible for detecting underground oil deposits. GeoSurvComp works with one large rec