标签:
Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 4606 | Accepted: 2615 |
Description
Input
Output
Sample Input
7 1 1 1 1 1 1 1 1 3 2 3 6 4 7 4 4 5 3 5 0 0
Sample Output
5
Source
POJ 2342
题目意思:
求一棵树的最小点权覆盖;
解题思路:
树状dp,状态转移方程为:
dp[i][0]=max(dp[son1][0],dp[son1][1])+max(dp[son2][0],dp[son2][1])+...max(dp[sonm][0],dp[sonm][1]);
dp[i][1]=sum(dp[son][0]);
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cstdio> 6 using namespace std; 7 const int maxn=6007; 8 bool visit[maxn]; 9 int value[maxn]; 10 int head[maxn]; 11 int dp[maxn][2]; 12 int sum=0; 13 int n; 14 struct node 15 { 16 int to,next; 17 }; 18 node tree[maxn]; 19 void init() 20 { 21 memset(head,-1,sizeof(head)); 22 memset(visit,0,sizeof(visit)); 23 memset(dp,0,sizeof(dp)); 24 memset(value,0,sizeof(value)); 25 sum=0; 26 } 27 void AddEdge(int u,int v) 28 { 29 tree[sum].to=v; 30 tree[sum].next=head[u];head[u]=sum; 31 sum++; 32 } 33 void dfs_tree(int point) 34 { 35 int res0=0,res1=0; 36 if(visit[point]) return; 37 visit[point]=1; 38 for(int i=head[point];i!=-1;i=tree[i].next) 39 { 40 if(!visit[tree[i].to]) dfs_tree(tree[i].to); 41 res1+=dp[tree[i].to][0]; 42 res0+=max(dp[tree[i].to][0],dp[tree[i].to][1]); 43 } 44 dp[point][0]=res0; 45 dp[point][1]=res1+value[point]; 46 } 47 int main() 48 { 49 // freopen("in.txt","r",stdin); 50 while(~scanf("%d",&n)){ 51 init(); 52 for(int i=1;i<=n;i++) 53 { 54 scanf("%d",&value[i]); 55 } 56 int a,b; 57 while(1) 58 { 59 scanf("%d %d",&a,&b); 60 if(a==0&&b==0) break; 61 AddEdge(b,a); 62 visit[a]=1; 63 } 64 int root; 65 for(int i=1;i<=n;i++) 66 { 67 if(visit[i]==0) root=i; 68 } 69 memset(visit,0,sizeof(visit)); 70 dfs_tree(root); 71 int ans=max(dp[root][0],dp[root][1]); 72 printf("%d\n",ans); 73 } 74 return 0; 75 }
标签:
原文地址:http://www.cnblogs.com/codeyuan/p/4312174.html