标签:
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 4976 | Accepted: 2734 |
Description
Input
Output
Sample Input
9 6
3 2 2 3 2 9 3
2 4 2 5 2
3 6 2 7 2 8 2
4 3 3 3 1 1
Sample Output
5
Source
树形DP,f[当前结点][连接的客户端数]=花费
最后对f[根节点][j]扫描,找到使f为正的最大j,即是答案。
1 /*by SilverN*/ 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<cstdio> 6 #include<cmath> 7 using namespace std; 8 const int INF=0x3f3f3f3f; 9 const int mxn=3200; 10 struct edge{ 11 int v,dis; 12 int nxt; 13 }e[mxn]; 14 int hd[mxn],cnt=0; 15 void add_edge(int u,int v,int dis){ 16 e[++cnt].v=v;e[cnt].dis=dis;e[cnt].nxt=hd[u];hd[u]=cnt; 17 return; 18 } 19 int n,m; 20 int num[mxn]; 21 int f[mxn][mxn]; 22 void dp(int u){ 23 int i,j,k; 24 for(i=hd[u];i;i=e[i].nxt){ 25 int v=e[i].v; 26 dp(v); 27 num[u]+=num[v]; 28 for(j=num[u];j;--j){ 29 for(k=num[v];k;--k){ 30 f[u][j]=max(f[u][j],f[u][j-k]+f[v][k]-e[i].dis); 31 } 32 } 33 } 34 return; 35 } 36 int main(){ 37 scanf("%d%d",&n,&m); 38 int i,j,k; 39 int u,v,d; 40 for(i=1;i<=n-m;i++){ 41 scanf("%d",&k); 42 for(j=1;j<=k;j++){ 43 scanf("%d%d",&v,&d); 44 add_edge(i,v,d); 45 } 46 } 47 for(i=1;i<=n;i++) 48 for(j=1;j<=m;j++) 49 f[i][j]=-INF; 50 for(i=n-m+1;i<=n;i++){num[i]=1;scanf("%d",&f[i][1]);} 51 dp(1); 52 for(i=m;i>=0;i--){ 53 if(f[1][i]>=0){ 54 printf("%d\n",i); 55 break; 56 } 57 } 58 return 0; 59 }
标签:
原文地址:http://www.cnblogs.com/SilverNebula/p/5916227.html