LightOj 1230 Placing Lampposts(树形DP)

题意:给定一个森林。每个节点上安装一个灯可以覆盖与该节点相连的所有边。选择最少的节点数num覆盖所有的边。在num最小的前提下,合理放置num个灯使得被两个灯覆盖的边最多?

思路:F[i][0]代表没放灯,F[i][1]代表放了灯,G[i]类似。

 1 #include<algorithm>
 2 #include<cstdio>
 3 #include<cmath>
 4 #include<cstring>
 5 #include<iostream>
 6 int f[1005][2],g[1005][2];
 7 int tot,go[200005],first[200005],next[200005];
 8 int n,m;
 9 int read(){
10     char ch=getchar();int t=0,f=1;
11     while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
12     while ('0'<=ch&&ch<='9'){t=t*10+ch-'0';ch=getchar();}
13     return t*f;
14 }
15 void insert(int x,int y){
16     tot++;
17     go[tot]=y;
18     next[tot]=first[x];
19     first[x]=tot;
20 }
21 void add(int x,int y){
22     insert(x,y);insert(y,x);
23 }
24 void dfs(int x,int fa){
25     f[x][0]=0;g[x][0]=0;
26     f[x][1]=1;g[x][1]=0;
27     for (int i=first[x];i;i=next[i]){
28         int pur=go[i];
29         if (pur==fa) continue;
30         dfs(pur,x);
31         if (f[pur][0]<f[pur][1]||(f[pur][0]==f[pur][1]&&g[pur][0]>g[pur][1]+1)){
32             f[x][1]+=f[pur][0];
33             g[x][1]+=g[pur][0];
34         }else{
35             f[x][1]+=f[pur][1];
36             g[x][1]+=g[pur][1]+1;
37         }
38         f[x][0]+=f[pur][1];
39         g[x][0]+=g[pur][1];
40     }
41 }
42 int main(){
43     int T;
44     scanf("%d",&T);
45     for (int Tcase=1;Tcase<=T;Tcase++){
46         n=read();m=read();
47         tot=0;
48         for (int i=1;i<=n;i++) first[i]=g[i][0]=g[i][1]=0,f[i][0]=f[i][1]=-1;
49         for (int i=1;i<=m;i++){
50             int x=read(),y=read();
51             x++;y++;
52             add(x,y);
53         }
54         int ans1=0,ans2=0;
55         for (int i=1;i<=n;i++)
56          if (f[i][0]==-1&&f[i][1]==-1){
57             dfs(i,0);
58             if (f[i][0]<f[i][1]||(f[i][0]==f[i][1]&&g[i][0]>g[i][1])){
59                 ans1+=f[i][0];
60                 ans2+=g[i][0];
61             }else{
62                 ans1+=f[i][1];
63                 ans2+=g[i][1];
64             }
65          }
66         printf("Case %d: %d %d %d\n",Tcase,ans1,ans2,m-ans2); 
67     }
68 }

 

posted @ 2016-06-02 17:48  GFY  阅读(189)  评论(0编辑  收藏  举报