• luogu2607/bzoj1040 [ZJOI2008]骑士 (基环树形dp)


    N个点,每个点发出一条边,那么这个图的形状一定是一个基环树森林(如果有重边就会出现森林)

    那我做f[0][x]和f[1][x]分别表示对于x子树,x这个点选还是不选所带来的最大价值

    然后就变成了这好几个环上不能选相邻的点,最大的价值和

    我们把这个环从N到1处断开,然后钦定一下1选还是不选,统计一下答案就可以了。

      1 #include<bits/stdc++.h>
      2 #define pa pair<int,int>
      3 #define ll long long
      4 using namespace std;
      5 const int maxn=1000010;
      6 
      7 inline ll rd(){
      8     ll x=0;char c=getchar();int neg=1;
      9     while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();}
     10     while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
     11     return x*neg;
     12 }
     13 
     14 int N;
     15 int eg[maxn*2][2],egh[maxn],ect;
     16 int dep[maxn],fa[maxn];
     17 int root[maxn][2],pct,rh[maxn],rct;
     18 int stk[maxn],top[maxn];
     19 ll f[2][maxn];
     20 bool flag[maxn],isroot[maxn],connected[maxn];
     21 
     22 inline void adeg(int a,int b){
     23     eg[++ect][0]=b;eg[ect][1]=egh[a];egh[a]=ect;
     24 }
     25 inline void adrot(int a,int b){
     26     root[++rct][0]=b;root[rct][1]=rh[a];rh[a]=rct;
     27 }
     28 
     29 void dfs1(int ii,int x){
     30     flag[x]=1;
     31     //printf("%d %d %d
    ",x,fa[x],dep[x]);
     32     for(int i=egh[x];i!=-1;i=eg[i][1]){
     33         int b=eg[i][0];if(b==fa[x]) continue;
     34         //printf("#%d %d %d %d %d
    ",x,b,flag[b],i,eg[i][1]);
     35         if(flag[b]){
     36             if(connected[ii]) continue;
     37             int u=x,v=b,lca,cnt=0;
     38             if(dep[u]<dep[v]) swap(u,v);
     39             while(dep[u]!=dep[v]) adrot(ii,u),isroot[u]=1,u=fa[u];
     40             while(u!=v){
     41                 isroot[u]=isroot[v]=1;
     42                 adrot(ii,u);
     43                 stk[++cnt]=v;
     44                 u=fa[u];v=fa[v];
     45             }lca=u;isroot[lca]=1;adrot(ii,lca);
     46             for(int j=cnt;j;j--) adrot(ii,stk[j]);
     47             connected[ii]=1;
     48         }else{
     49             dep[b]=dep[x]+1;fa[b]=x;
     50             dfs1(ii,b);
     51         }
     52     }
     53 }
     54 
     55 void dfs2(int x,int F){
     56     for(int i=egh[x];i!=-1;i=eg[i][1]){
     57         int b=eg[i][0];if(b==F||isroot[b]) continue;
     58         dfs2(b,x);
     59         f[0][x]+=max(f[0][b],f[1][b]);
     60         f[1][x]+=f[0][b];
     61     }
     62 }
     63 
     64 inline ll solve(int p){
     65     if(rh[p]==-1) return max(f[0][top[p]],f[1][top[p]]);
     66     ll re=0;
     67     ll g1=f[1][root[rh[p]][0]],g0=0;
     68     for(int i=root[rh[p]][1];i!=-1;i=root[i][1]){
     69         ll xx=max(g0,g1);
     70         g1=g0+f[1][root[i][0]];
     71         g0=xx+f[0][root[i][0]];
     72     }re=max(re,g0);
     73     
     74     g1=0,g0=f[0][root[rh[p]][0]];
     75     for(int i=root[rh[p]][1];i!=-1;i=root[i][1]){
     76         ll xx=max(g0,g1);
     77         g1=g0+f[1][root[i][0]];
     78         g0=xx+f[0][root[i][0]];
     79     }re=max(re,max(g0,g1));
     80     return re;
     81 }
     82 
     83 int main(){
     84     int i,j,k;
     85     //freopen("2607.in","r",stdin);
     86     N=rd();memset(egh,-1,sizeof(egh));
     87     for(i=1;i<=N;i++){
     88         int a=rd(),b=rd();
     89         f[1][i]=a;
     90         adeg(i,b);adeg(b,i);
     91     }memset(rh,-1,sizeof(rh));
     92     for(i=1;i<=N;i++){
     93         if(!flag[i]) top[++pct]=i,dfs1(pct,i);
     94     }
     95     //for(i=1;i<=rct;i++) printf("!%d %d %d
    ",i,root[i][0],root[i][1]);
     96     for(i=1;i<=rct;i++) dfs2(root[i][0],0);
     97     ll ans=0;
     98     for(i=1;i<=pct;i++){
     99         ans+=solve(i);
    100     }
    101     printf("%lld
    ",ans);
    102     
    103     return 0;
    104 }
  • 相关阅读:
    仿佛看到了曾经在电子厂的自己
    TP5 condition 多个条件如何写
    电子数据时代我该如何保存我的数据?
    Shell脚本查询磁盘数量
    缺少维生素?
    html5的页面在IOS中,按钮 变成圆角怎么办?
    生物信息数据分析准则
    用variant的数据来推导基因表达 | Imputation of Expression Using PrediXcan
    Rare-Variant Association Analysis | 罕见变异的关联分析
    英语语法
  • 原文地址:https://www.cnblogs.com/Ressed/p/9648859.html
Copyright © 2020-2023  润新知