zoukankan      html  css  js  c++  java
  • ZJOI 骑士

    题目链接 https://www.luogu.com.cn/problem/P2607

    分析

    这道题看了的确很眼熟,加一个0/1状态就可以进行转移了,后来才知道是没有上司的舞会那道题的思路。
    打完一个树形DP后感觉有些问题—————它一开始的状态可能不是一棵树啊,的确如果是树的话,和没有上司的舞会是一个类型,那它不是树,又是什么呢?百度后得知,这其实是个基环树,什么是基环树?
    基环树其实就是类似树的东西上边套了一个环,或者说环套在树上,看起来挺高端的但这个题用不到太高端的知识,只需要用到它的一个性质,在环上去掉一条边就会成为一棵树,求环的话可以用topsort也可以dfs,由于我看了半天topsort也不会实现,所以写了dfs。
    接下来要做的事情就是找到环上的一条边,并且把它断开,以两个端点分别为根节点跑树形dp,这里有一个小技巧,比如两端分别为(u)(v),以(u)为根节点时,默认(u)不选,为什么呢?因为如果(u)选了,那(v)一定不能选,这就增大了我们在dp时的判断难度,所以默认它不选,那如果要选它呢?显然就在以(v)为根节点dp的时候考虑了。
    别的其实跟没有上司的舞会简直一模一样,不再赘述。

    #include<cstdio>
    #include<algorithm>
    #define ll long long
    using namespace std;
    const int N=1e6+100;
    struct Edge{
        int to,nxt;
    }e[N<<1];
    int val[N],Head[N],len=1;
    void Ins(int a,int b){
        e[++len].to=b;e[len].nxt=Head[a];Head[a]=len;
    }
    int u,v,E;bool vis[N];
    ll dp[N][2];
    void find(int x,int fa){
        vis[x]=1;
        for(int i=Head[x];i;i=e[i].nxt){
            if((i^1)==fa)continue;
            int to=e[i].to;
            if(vis[to]){
                u=x,v=to;
                E=i;continue;
            }
            find(to,i);
        }
    }
    void dfs(int x,int fa){
        dp[x][0]=0;
        dp[x][1]=val[x];
        for(int i=Head[x];i;i=e[i].nxt){
            if((i^1)==fa||i==E||(i^1)==E)continue;
            int to=e[i].to;
            dfs(to,i);
            dp[x][1]+=dp[to][0];
            dp[x][0]+=max(dp[to][1],dp[to][0]);
        }
    }
    int main(){
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            int b;
            scanf("%d%d",&val[i],&b);
            Ins(i,b);Ins(b,i);
        }
        ll ans=0;
        for(int i=1;i<=n;i++){
            if(vis[i])continue;
            find(i,-1);
            dfs(u,-1);
            ll tep=dp[u][0];
            dfs(v,-1);
            ans+=max(tep,dp[v][0]);
        }
        printf("%lld
    ",ans);
    }
    
  • 相关阅读:
    【codeforces 787B】Not Afraid
    【codeforces 787A】The Monster
    【codeforces 787C】Berzerk
    【t046】牛跳
    【BZOJ 1033】 [ZJOI2008]杀蚂蚁antbuster(判断线段是否和圆相交)
    Java Web整合开发(81)
    用户、权限管理
    链表
    T1230 元素查找 codevs
    T3139 栈练习3 codevs
  • 原文地址:https://www.cnblogs.com/anyixing-fly/p/12762820.html
Copyright © 2011-2022 走看看