【Luogu】P2607骑士(基环树DP)

  题目链接

  这题……好吧我比着题解打的

  题解连接

#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<cctype>
#include<algorithm>
#define maxn 1000200
using std::max;
inline long long read(){
    long long num=0,f=1;
    char ch=getchar();
    while(!isdigit(ch)){
        if(ch=='-')    f=-1;
        ch=getchar();
    }
    while(isdigit(ch)){
        num=num*10+ch-'0';
        ch=getchar();
    }
    return num*f;
}

struct Edge{
    int next,to;
}edge[maxn*2];
int head[maxn],num;
inline void add(int from,int to){
    edge[++num]=(Edge){head[from],to};
    head[from]=num;
}

int fa[maxn];
long long f[maxn][2];
bool vis[maxn];
int q[maxn];
int ban;
long long ans;
void dfs(int x){
    vis[x]=1;
    f[x][0]=0;
    f[x][1]=q[x];
    for(int i=head[x];i;i=edge[i].next){
        int to=edge[i].to;
        if(to==ban){
            f[to][1]=-100000000;
            continue;
        }
        dfs(to);
        f[x][0]+=max(f[to][1],f[to][0]);
        f[x][1]+=f[to][0];
    }
    return;
}
        

int main(){
    int n=read();
    for(int i=1;i<=n;++i){
        q[i]=read();
        fa[i]=read();
        add(fa[i],i);
    }
    for(int i=1;i<=n;++i){ 
        if(!vis[i]){
            int p=i;
            while(!vis[p]){
                vis[p]=1;
                p=fa[p];
            }
            ban=p;
            dfs(p);
            long long now=max(f[p][0],f[p][1]);
            p=fa[p];ban=p;
            dfs(p);
            ans+=max(now,max(f[p][1],f[p][0]));
        }
    }
    printf("%lld",ans);
    return 0;
}

 

posted @ 2018-01-03 16:26  Konoset  阅读(145)  评论(0编辑  收藏  举报