zoukankan      html  css  js  c++  java
  • 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
    ",Tcase,ans1,ans2,m-ans2); 
    67     }
    68 }
  • 相关阅读:
    模拟google分页效果
    真理胜于一切 JAVA模拟表单提交
    springboot @vaule注解失效解决办法
    安装cnpm
    公众号微信支付开发
    vue去掉链接中的#
    springboot集成mongoDB简易使用
    Spring boot中使用aop详解
    Promise 的基础用法
    MySQL的if,case语句使用总结
  • 原文地址:https://www.cnblogs.com/qzqzgfy/p/5553899.html
Copyright © 2011-2022 走看看