有个要注意的地方在代码中标出来了
这题需要优化,就是开个数组记录节点i已经有多少个user了,不然的话会超时
AC代码如下:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define MAX 1<<30
typedef struct{
int cost, to, next;
}Node;
int dp[3001][3001];
int N, M;
Node edge[3001];
int head[3001], tot;
int value[3001];
int num[3001];
int temp[3001];
void add_edge( int i, int j, int cost ){
edge[tot].next = head[i];
edge[tot].cost = cost;
edge[tot].to = j;
head[i] = tot++;
}
void DFS( int n ){
//dp[n][0] = 0;
for( int i = head[n]; i != -1; i = edge[i].next ){
int to = edge[i].to;
DFS( to );
int cost = edge[i].cost;
//if( to > N - M ){
// for( int j = M; j > 0; j-- ){
// if( dp[n][j-1] != -MAX ){
// dp[n][j] = max( dp[n][j], dp[n][j-1] + value[to] - cost );
// }
// }
//}else{
for( int j = 0; j <= num[n]; j++ ){//这个不能少!!!
temp[j] = dp[n][j];
}
for( int j = 0; j <= num[n]; j++ ){
for( int k = 1; k <= num[to]; k++ ){
dp[n][j+k] = max( dp[n][j+k], temp[j] + dp[to][k] - cost );
}
}
//}
num[n] += num[to];
}
}
int main(){
while( scanf( "%d%d", &N, &M ) != EOF ){
memset( head, -1, sizeof( head ) );
memset( value, 0, sizeof( value ) );
tot = 0;
for( int i = 1; i < 3001; i++ ){
for( int j = 1; j < 3001; j++ ){
dp[i][j] = - MAX;
}
}
for( int i = 1; i <= N - M; i++ ){
int temp, temp1, temp2;
cin >> temp;
num[i] = 0;
for( int j = 0; j < temp; j++ ){
cin >> temp1 >> temp2;
add_edge( i, temp1, temp2 );
}
}
for( int i = N - M + 1; i <= N; i++ ){
cin >> value[i];
num[i] = 1;
dp[i][1] = value[i];
}
DFS( 1 );
int ans = M;
for( ; ans > 0; ans-- ){
if( dp[1][ans] >= 0 ){
break;
}
}
cout << ans << endl;
}
return 0;
}