bzoj 1040: [ZJOI2008]骑士

Posted lxy8584099

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj 1040: [ZJOI2008]骑士相关的知识,希望对你有一定的参考价值。

 

 和仙人掌有所不同? 应该是一样的啊。。。

 

/**************************************************************
    Problem: 1040
    User: lxy8584099
    Language: C++
    Result: Accepted
    Time:1916 ms
    Memory:40868 kb
****************************************************************/
 
// by pig~~
#include<cstdio>
#include<cstring>
#define ll long long
using namespace std;
/*
    思路:
    因为每个人只有一个特别讨厌的人 所以建边后 肯定成环或者是单独一个点(看作环)
    对每个环进行DP 每次DP后最大值累加起来 
*/
const int N=1000050;
struct pp{int nxt,to;}e[N<<1];
int n,tot,val[N],head[N],u1,u2,E;
ll ans,f[N][2];// f[i][0/1]  表示 不取/取  这个点的最大值 
bool vis[N];
inline void add(int u,int v){e[tot].nxt=head[u];e[tot].to=v;head[u]=tot++;}
inline ll max(ll a,ll b){return a>b?a:b;}
inline ll min(ll a,ll b){return a>b?b:a;}
inline void dfs(int u,int last)  
{
    vis[u]=1;
    for(int j=head[u];~j;j=e[j].nxt)
    {
        if((j^1)==last) continue; // 去掉返回边,不走回头路 
        int v=e[j].to;
        if(vis[v])
        {
            u1=u;u2=v;E=j;continue; // 找到环  选择切断的边 E,俩断点 u1,u2  
        }
        dfs(v,j);
    }
}
inline void DP(int u,int last)
{
    f[u][0]=0;f[u][1]=val[u];
    for(int j=head[u];~j;j=e[j].nxt)
    {
        if(((j^1)==last)||(j==E)||((j^1)==E)) continue; // 去掉返回边,不走我们选择断掉的路 
        int v=e[j].to;
        DP(v,j);
        f[u][1]+=f[v][0];
        f[u][0]+=max(f[v][1],f[v][0]);
    }
}
int main()
{
//    freopen("knight.in","r",stdin);
//    freopen("knight.out","w",stdout);
    memset(head,-1,sizeof(head));
    scanf("%d",&n);
    for(int i=1,v;i<=n;i++)
    {
        scanf("%d%d",&val[i],&v);add(i,v);add(v,i);//建边 从0开始 用位运算方便求出同边 
    }
    for(int i=1;i<=n;i++) 
    {
        if(vis[i]) continue;
        dfs(i,-2);ll all;
        /*
            本次DP的答案在f[u1][0] 或 f[u2][0] 中
            因为f[u1][1]的结果可能会包含取到 u2 ,
            同理 f[u2][1]的结果可能会包含取到 u1. 
        */
        DP(u1,-1);
        all=f[u1][0];
        DP(u2,-1);
        all=max(all,f[u2][0]);
        ans+=all;
    }
    printf("%lld
",ans);
    return 0;
}
/*
 
3
20 3
20 3
30 1
 
 
*/

 

以上是关于bzoj 1040: [ZJOI2008]骑士的主要内容,如果未能解决你的问题,请参考以下文章

bzoj1040[ZJOI2008]骑士

BZOJ1040: [ZJOI2008]骑士

bzoj 1040: [ZJOI2008]骑士 树形dp

bzoj 1040: [ZJOI2008]骑士

bzoj1040: [ZJOI2008]骑士

bzoj1040: [ZJOI2008]骑士