zoukankan      html  css  js  c++  java
  • BZOJ1040 [ZJOI2008]骑士 环套树/dp

    借题区别了一下环套树和仙人掌

    常见做法是拆环做2次DP

    邻接表的话也能做,vis一下封堵点,第二次再vis到放行就好

    //#include<bits/stdc++.h>  
    #pragma comment(linker, "/STACK:1024000000,1024000000")   
    #include<stdio.h>  
    #include<algorithm>  
    #include<queue>  
    #include<string.h>  
    #include<iostream>  
    #include<math.h>  
    #include<set>  
    #include<map>  
    #include<vector>  
    #include<iomanip>  
    using namespace std;  
    #define ll long long  
    #define pb push_back  
    #define FOR(a) for(int i=1;i<=a;i++)  
    const int inf=0x3f3f3f3f;  
     
    const int maxn=1e6+5;    
     
    ll a[maxn];
    int n;
    
    struct EDGE{
    	int u,v,nxt;
    }G[maxn<<1];
    int tot,head[maxn];
    void init(){tot=0;memset(head,-1,sizeof head);}
    void addedge(int u,int v){
    	G[tot]=(EDGE){u,v,head[u]};head[u]=tot;tot++;
    	G[tot]=(EDGE){v,u,head[v]};head[v]=tot;tot++;
    }
    bool s[maxn<<1];
    
    ll f[maxn][2];
    
    bool flag;
    int vis[maxn];
    int l,r;
    
    void dfs(int u,int fa){
    	vis[u]=1;
    	for(int i=head[u];~i && !flag;i=G[i].nxt){
    		if(G[i].v!=fa){
    			if(vis[G[i].v]){
    				l=u,r=G[i].v;
    				s[i]=s[i^1]=1;
    				flag=1;
    				break;
    			}
    			dfs(G[i].v,u);
    		}
    	}
    }
    void dp(int u,int fa,int fob){
    	vis[u]=1;
    	if(u!=fob)f[u][1]=a[u];
    	else f[u][1]=0;
    	f[u][0]=0;
    	for(int i=head[u];~i;i=G[i].nxt){
    		if(G[i].v!=fa && !s[i]){
    			dp(G[i].v,u,fob);
    			f[u][0]+=max(f[G[i].v][0],f[G[i].v][1]);
    			f[u][1]+=f[G[i].v][0];
    		}
    	}
    }
    
    int main(){
    	scanf("%d",&n);
    	init();
    	for(int i=1,x;i<=n;i++){
    		scanf("%lld%d",&a[i],&x);
    		addedge(i,x);
    	}
    	ll ans=0;
    	for(int i=1;i<=n;i++){
    		if(!vis[i]){
    			flag=false;
    			dfs(i,0);
    			ll tmp=0;
    			dp(l,0,r);
    
    			tmp=max(f[l][0],f[l][1]);
    
    			dp(r,0,l);
    			tmp=max(tmp,max(f[r][0],f[r][1]));
    				
    			ans+=tmp;
    		}
    	}
    	printf("%lld
    ",ans);
    }


  • 相关阅读:
    集合类
    ajax技术
    Java中的Runnable、Callable、Future、FutureTask的区别与示例
    python 检测文件编码等
    android发送/接收Json包含中文的处理
    android 获取 imei号码 及相关信息
    RelativeLayout常用属性介绍
    Android之读取 AndroidManifest.xml 中的数据
    Java中int与Integer
    Handler sendMessage 与 obtainMessage (sendToTarget)
  • 原文地址:https://www.cnblogs.com/Drenight/p/8611211.html
Copyright © 2011-2022 走看看