zoukankan      html  css  js  c++  java
  • LightOJ1230 Placing Lampposts(DP)

    题目大概说给一个森林求其最小点覆盖数,同时在最小点覆盖条件下输出最多有多少条边被覆盖两次。

    • dp[0/1][u]表示以u为根的子树内的边都被覆盖且u不属于/属于覆盖集所需的最少点数
    • 另外,用cnt[0/1][u]表示满足dp[0/1][u]状态下子树内被覆盖两次最多的边数
    • 对于dp[0][u]只能从其孩子结点v的dp[1][v]转移,而dp[1][u]从dp[0][v]或者dp[1][v]转移,转移时如果同时转移更新cnt的值。。

    思路要清晰。。转移细节要注意。。另外注意是森林。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 using namespace std;
     5 #define MAXN 1111
     6 
     7 struct Edge{
     8     int v,next;
     9 }edge[MAXN<<1];
    10 int NE,head[MAXN];
    11 void addEdge(int u,int v){
    12     edge[NE].v=v; edge[NE].next=head[u];
    13     head[u]=NE++;
    14 }
    15 
    16 int d[2][MAXN],cnt[2][MAXN];
    17 bool vis[MAXN];
    18 void dfs(int u,int fa){
    19     cnt[0][u]=cnt[1][u]=0;
    20     d[0][u]=0;
    21     d[1][u]=1;
    22     vis[u]=1;
    23     for(int i=head[u]; i!=-1; i=edge[i].next){
    24         int v=edge[i].v;
    25         if(v==fa) continue;
    26         dfs(v,u);
    27         d[0][u]+=d[1][v];
    28         cnt[0][u]+=cnt[1][v];
    29         if(d[0][v]>d[1][v]){
    30             cnt[1][u]+=cnt[1][v]+1;
    31             d[1][u]+=d[1][v];
    32         }else if(d[0][v]<d[1][v]){
    33             cnt[1][u]+=cnt[0][v];
    34             d[1][u]+=d[0][v];
    35         }else{
    36             cnt[1][u]+=max(cnt[0][v],cnt[1][v]+1);
    37             d[1][u]+=d[1][v];
    38         }
    39     }
    40 }
    41 
    42 int main(){
    43     int t,n,m;
    44     scanf("%d",&t);
    45     for(int cse=1; cse<=t; ++cse){
    46         scanf("%d%d",&n,&m);
    47         NE=0;
    48         memset(head,-1,sizeof(head));
    49         int a,b;
    50         for(int i=0; i<m; ++i){
    51             scanf("%d%d",&a,&b);
    52             addEdge(a,b);
    53             addEdge(b,a);
    54         }
    55         memset(vis,0,sizeof(vis));
    56         int res=0,mm=0;
    57         for(int i=0; i<n; ++i){
    58             if(!vis[i]){
    59                 dfs(i,i);
    60                 if(d[0][i]>d[1][i]){
    61                     res+=d[1][i];
    62                     mm+=cnt[1][i];
    63                 }else if(d[0][i]<d[1][i]){
    64                     res+=d[0][i];
    65                     mm+=cnt[0][i];
    66                 }else{
    67                     res+=d[0][i];
    68                     mm+=max(cnt[0][i],cnt[1][i]);
    69                 }
    70             }
    71         }
    72         printf("Case %d: %d %d %d
    ",cse,res,mm,m-mm);
    73     }
    74     return 0;
    75 }
  • 相关阅读:
    容器适配器之queue
    STL之deque
    STL之list
    STL之multiset
    STL之multimap
    STL之set
    string
    命名空间
    Windows Live Writer教程及代码高亮工具
    STL之vector
  • 原文地址:https://www.cnblogs.com/WABoss/p/5671617.html
Copyright © 2011-2022 走看看