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;
}
View Code

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

posted on 2017-09-13 00:24  FriskyPuppy  阅读(149)  评论(0编辑  收藏  举报

导航