pku 1052 昂贵的聘礼
题意:中文。。
思路:
这里的等级限制是,与他本身交易的以及间接交易的都不能超过m。所以我们在树形DP时,维护可行区间即可。 关键是在维护可行区间时卡住了。
View Code
#include <iostream> #include <cstdio> #include <cmath> #include <vector> #include <cstring> #include <algorithm> #include <string> #include <set> #include <functional> #include <numeric> #include <sstream> #include <stack> #include <map> #include <queue> #define CL(arr, val) memset(arr, val, sizeof(arr)) #define ll unsigned __int64 #define inf 0x7f7f7f7f #define lc l,m,rt<<1 #define rc m + 1,r,rt<<1|1 #define pi acos(-1.0) #define L(x) (x) << 1 #define R(x) (x) << 1 | 1 #define MID(l, r) (l + r) >> 1 #define Min(x, y) (x) < (y) ? (x) : (y) #define Max(x, y) (x) < (y) ? (y) : (x) #define E(x) (1 << (x)) #define iabs(x) (x) < 0 ? -(x) : (x) #define OUT(x) printf("%I64d\n", x) #define lowbit(x) (x)&(-x) #define Read() freopen("din.txt", "r", stdin) #define Write() freopen("dout.txt", "w", stdout); #define N 107 using namespace std; int len[N][N]; int level[N],val[N]; int dp[N]; int n,m; int dfs(int u,int Li,int Ri) { int i; if (dp[u]) return dp[u]; dp[u] = val[u]; for (i = 1; i <= n; ++i) { if (len[u][i] && level[i] >= Li - m && level[i] <= Ri + m) { dp[u] = min(dp[u],dfs(i,Li > level[i]?Li:level[i],Ri < level[i]? Ri:level[i]) + len[u][i]); } } return dp[u]; } int main() { // Read(); int P,L,X; int T,V; int i,j; while (~scanf("%d%d",&m,&n)) { CL(len,0); CL(dp,0); for (i = 1; i <= n; ++i) { scanf("%d%d%d",&P,&L,&X); level[i] = L; val[i] = P; for (j = 0; j < X; ++j) { scanf("%d%d",&T,&V); len[i][T] = V; } } printf("%d\n",dfs(1,level[1],level[1])); } return 0; }