zoukankan      html  css  js  c++  java
  • [BZOJ1040][ZJOI2008]骑士 基环树DP

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1040

    题目给出了$n$个点和$n$条无向边,即一棵基环树或者基环树森林。

    如果题目给的关系是在一棵树上,就是一道经典的树形DP。现在我们考虑转化一下。

    我们先找到那个环上的任意一条边,端点为u,v。加上这条边的影响仅仅是不能同时选择u和v。

    所以我们考虑去掉这条边再分类讨论。如果不选u,那么v任意选;如果不选v,那么u任意选。那么DP的时候强制不走这条边,同时取两种不选根节点的最大值作为答案就行了。

     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 using namespace std;
     5 typedef long long ll;
     6 int inline readint(){
     7     int Num;char ch;
     8     while((ch=getchar())<'0'||ch>'9');Num=ch-'0';
     9     while((ch=getchar())>='0'&&ch<='9') Num=Num*10+ch-'0';
    10     return Num;
    11 }
    12 int N,val[1000010];
    13 int to[2000010],ne[2000010],fir[1000010],cnt=-1;
    14 void add(int a,int b){
    15     to[++cnt]=b;
    16     ne[cnt]=fir[a];
    17     fir[a]=cnt;
    18 }
    19 bool vis[1000010];
    20 int U,V,E;
    21 void Dfs(int x,int fa){
    22     vis[x]=true;
    23     for(int i=fir[x];i!=-1;i=ne[i]){
    24         int v=to[i];
    25         if(v!=fa){
    26             if(vis[v]){
    27                 U=x;
    28                 V=v;
    29                 E=i;
    30             }
    31             else Dfs(v,x);
    32         }
    33     }
    34 }
    35 ll f[1000010],g[1000010];
    36 void Dp(int x,int fa){
    37     f[x]=val[x];
    38     g[x]=0;
    39     for(int i=fir[x];i!=-1;i=ne[i]){
    40         int v=to[i];
    41         if(i==E||(i^1)==E||v==fa) continue;
    42         Dp(v,x);
    43         f[x]+=g[v];
    44         g[x]+=max(f[v],g[v]);
    45     }
    46 }
    47 int main(){
    48     memset(fir,-1,sizeof(fir));
    49     N=readint();
    50     for(int i=1;i<=N;i++){
    51         val[i]=readint();
    52         int tmp=readint();
    53         add(i,tmp);
    54         add(tmp,i);
    55     }
    56     ll ans=0;
    57     for(int i=1;i<=N;i++){
    58         if(!vis[i]){
    59             Dfs(i,0);
    60             Dp(U,0);
    61             ll tmp=g[U];
    62             Dp(V,0);
    63             tmp=max(tmp,g[V]);
    64             ans+=tmp;
    65         }
    66     }
    67     printf("%lld
    ",ans);
    68     return 0;
    69 }
  • 相关阅读:
    大数据基础文献综述
    牛客网数据库SQL实战
    Leetcode with Python
    tinyMCE
    HTTP LVS
    采坑大全
    Hadoop 解除 NameNode is in safe mode
    R语言采坑系列——Warning message: In validDetails.polygon(x) : 强制改变过程中产生了NA
    .Net中的异步编程
    知识点4
  • 原文地址:https://www.cnblogs.com/halfrot/p/7643178.html
Copyright © 2011-2022 走看看