zoukankan      html  css  js  c++  java
  • UVA

    题目链接

    题意:给你一个树形图,让你把其中若干个结点染成黑色,其余的染成白色,使得任意一个白色结点都恰好与一个黑色结点相邻。

    解法比较容易,和树上的最大独立集类似,取一个结点作为树根,对每个结点分三种情况讨论即可:自己是黑色,自己是白色而父亲是黑色,自己和父亲都是白色。

    但关键在于这道题如果用inf来作为不合法状态的dp值的话,会导致在dp的过程中有多个inf相加而炸掉!!习惯把inf设成0x3f3f3f3f或者0x7fffffff的选手们要杯具了。

    解决方法有很多,比如把inf设小一点,把int改成longlong等等都可以。比较保险的方法是在运算的过程中如果超过inf就立即改成inf,这样只要保证两个inf相加不会溢出就行了,这时候0x3f3f3f3f的好处就体现出来了,两个0x3f3f3f3f相加之后仍不超过int上限。

    这是我第一次爆inf的经历,为什么其他的题都不爆inf,偏偏在这道题上爆了呢?我也想不出一个比较中肯的解释,大概是inf的存在就是为了简化判断,而本身没什么实际意义吧,因此会出现不可预料的结果应该也是正常的,引以为戒。

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const int N=1e4+10,inf=0x3f3f3f3f;
     5 struct E {int v,nxt;} e[N<<1];
     6 int n,d[N][3],hd[N],ne;
     7 void addedge(int u,int v) {e[ne]= {v,hd[u]},hd[u]=ne++;}
     8 void dp(int u,int fa) {
     9     for(int i=hd[u]; ~i; i=e[i].nxt) {
    10         int v=e[i].v;
    11         if(v==fa)continue;
    12         dp(v,u);
    13     }
    14     d[u][0]=1,d[u][1]=0,d[u][2]=inf;
    15     for(int i=hd[u]; ~i; i=e[i].nxt) {
    16         int v=e[i].v;
    17         if(v==fa)continue;
    18         d[u][0]+=min(d[v][0],d[v][1]);
    19         d[u][0]=min(d[u][0],inf);
    20     }
    21     for(int i=hd[u]; ~i; i=e[i].nxt) {
    22         int v=e[i].v;
    23         if(v==fa)continue;
    24         d[u][1]+=d[v][2];
    25         d[u][1]=min(d[u][1],inf);
    26     }
    27     for(int i=hd[u]; ~i; i=e[i].nxt) {
    28         int v=e[i].v;
    29         if(v==fa)continue;
    30         d[u][2]=min(d[u][2],d[u][1]+d[v][0]-d[v][2]);
    31         d[u][2]=min(d[u][2],inf);
    32     }
    33 }
    34 
    35 int main() {
    36     while(scanf("%d",&n)==1) {
    37         memset(hd,-1,sizeof hd),ne=0;
    38         for(int i=1; i<n; ++i) {
    39             int u,v;
    40             scanf("%d%d",&u,&v);
    41             addedge(u,v);
    42             addedge(v,u);
    43         }
    44         dp(1,-1);
    45         printf("%d
    ",min(d[1][0],d[1][2]));
    46         int ff;
    47         scanf("%d",&ff);
    48         if(ff==-1)break;
    49     }
    50     return 0;
    51 }
  • 相关阅读:
    javascript运算符
    javascript字符串转数字
    javascript的变量声明和数据类型
    javascript的历史和入门
    CSS中定位
    CSS中盒子模型
    CSS操作表格的边框和表格的属性示例代码
    常用的CSS样式示例代码
    CSS伪类选择器
    CSS选择器
  • 原文地址:https://www.cnblogs.com/asdfsag/p/10372272.html
Copyright © 2011-2022 走看看