hdu 4276 树形DP

来源:互联网 发布:淘宝手机充值代付 编辑:程序博客网 时间:2024/05/29 23:44

这题看了点别人的思路。

先是用一次广搜,搜出从1到N的最短路径,判断是否小于T(就是判断下能否逃出去),然后将这条路径上的所有边的权值变成0,这样再进行一次树形DP那么刚刚为0的边一定会选进去,其他的边用DP选。有一点要注意,这时候权值要乘以2,因为要回来。不懂的话,画下图就知道了。

AC代码如下:

#include <iostream>#include <cstdio>#include <cstring>#include <vector>#include <queue>using namespace std;typedef struct{int to;int next;int length;}Edge;typedef struct{vector<int> edge;int time;int now;}Node;Edge edge[202];int head[101];int N, T;int value[101];int tot;int dp[101][501];bool visit[101];int sum;inline int max( int a, int b ){return ( a > b ? a : b );}void add_edge( int a, int b, int c ){edge[tot].to = b;edge[tot].length = c;edge[tot].next = head[a];head[a] = tot++;edge[tot].to = a;edge[tot].length = c;edge[tot].next = head[b];head[b] = tot++;}void BFS(){bool mark[101];queue<Node> q;Node start;Node end;start.now = 1;start.time = 0;start.edge.clear();q.push( start );memset( mark, false, sizeof( mark ) );mark[1] = true;while( !q.empty() ){Node n = q.front();q.pop();if( n.now == N ){end = n;break;}int t = n.now;for( int i = head[t]; i != -1; i = edge[i].next ){Node temp = n;temp.now = edge[i].to;temp.edge.push_back( i );temp.time += edge[i].length;if( mark[temp.now] ){continue;}mark[temp.now] = true;q.push( temp );}}sum = 0;for( int i = 0; i < end.edge.size(); i++ ){sum += edge[end.edge[i]].length;edge[end.edge[i]].length = 0;}}void DFS( int n, int pre ){if( head[n] == -1 || ( edge[head[n]].to == pre && edge[head[n]].next == -1 ) ){for( int i = 0; i <= T; i++ ){dp[n][i] = value[n];}return;}for( int i = head[n]; i != -1; i = edge[i].next ){int t = edge[i].to;if( visit[t] ){continue;}if( t == pre ){continue;}visit[t] = true;DFS( t, n );for( int j = T; j >= 0; j-- ){for( int k = 0; k + 2 * edge[i].length <= j; k++ ){ dp[n][j] = max( dp[n][j], dp[n][j-k-2*edge[i].length] + dp[t][k] );}}}for( int i = 0; i <= T; i++ ){dp[n][i] += value[n];}}int main(){while( scanf( "%d%d", &N, &T ) != EOF ){memset( value, 0, sizeof( value ) );memset( head, -1, sizeof( head ) );tot = 0;for( int i = 1; i < N; i++ ){int temp1, temp2, temp3;cin >> temp1 >> temp2 >> temp3;add_edge( temp1, temp2, temp3 );}for( int i = 1; i <= N; i++ ){cin >> value[i];}BFS();if( sum <= T ){memset( dp, 0, sizeof( dp ) );memset( visit, 0, sizeof( visit ) );DFS( 1, 0 );cout << dp[1][T-sum] << endl;}else{cout << "Human beings die in pursuit of wealth, and birds die in pursuit of food!" << endl;}}return 0;}


 

原创粉丝点击