题目 http://poj.org/problem?id=2342
大致意思就是
输入n个结点,接下去的n行,表示1-n的每个结点分别具有的活跃值,在接下来去的n-1行,输入a,b,表示b是a的上司
输出由于直接有上司和下属关系的两个人不能同时参加party, 求出能让party活跃值最大的方案(求出最大的活跃值即可).
思路
每个结点有两种状态,参加和不参加,用0表示不参加,1表示参加
dp[i][1]表示第i个参与者参加了,dp[i][0]表示第i个参与者没有参加。
状态转移方程:dp[u][0] += max (dp[v][0], dp[v][1]) :表示上司没参加,其员工可以参加可以不参加
dp[u][1] += dp[v][0] : 表示若上司参加了,其员工一定不会参加
1 #include <iostream> 2 #include <string.h> 3 #include <algorithm> 4 using namespace std; 5 #define N 6006 6 int e; 7 int val[N],in[N],head[N],dp[N][2]; 8 struct node 9 { 10 int v,next; 11 }pe[N]; 12 void addedge(int u,int v) 13 { 14 pe[e].v = v; 15 pe[e].next = head[u]; 16 head[u] = e++; 17 } 18 int dfs(int u) 19 { 20 dp[u][0] = 0; 21 dp[u][1] = val[u]; 22 for(int i=head[u];i!=-1;i=pe[i].next) 23 { 24 int v = pe[i].v; 25 dfs(v); 26 dp[u][0] += max(dp[v][0],dp[v][1]); 27 dp[u][1] += dp[v][0]; 28 } 29 return max(dp[u][0],dp[u][1]); 30 } 31 int main() 32 { 33 int n,v,u; 34 cin>>n; 35 memset(head,-1,sizeof(head)); 36 e=0; 37 for(int i=1;i<=n;i++) 38 { 39 cin>>val[i]; 40 in[i]=0; //in 这个数组记录的是入度 41 } 42 while(cin>>v>>u && v+u!=0) 43 { 44 addedge(u,v); 45 in[v]++; 46 } 47 int ans=0; 48 for(int i=1;i<=n;i++) 49 { 50 if(!in[i]) 51 ans+=dfs(i); 52 } 53 cout<<ans<<endl; 54 return 0; 55 }
时间: 2024-10-08 10:29:34