zoukankan      html  css  js  c++  java
  • 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("=======
    ")
    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
    ", ans );
        }
        return 0;
    }
    View Code

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

  • 相关阅读:
    redis的常用命令及php-redis的使用
    mysql数据库基本操作
    php接口数据安全解决方案
    如何防止api接口被恶意调用或攻击
    virtualBox安装及调试
    PHP常用扩展
    memcached安装与应用
    Jmeter的基础使用(4)——添加服务器的监控
    Jmeter的基础使用(3)——使用实操
    Jmeter的基础使用(2)——线程的添加以及基本使用
  • 原文地址:https://www.cnblogs.com/FriskyPuppy/p/7513014.html
Copyright © 2011-2022 走看看