求助:(树形DP+基环树,未过,5WA1TLE,40’)
查看原帖
求助:(树形DP+基环树,未过,5WA1TLE,40’)
187086
whr080101楼主2020/8/20 12:58

RT

#include<bits/stdc++.h>
using namespace std;
inline bool id(const char ch) {
	return ch>='0'&&ch<='9';
}
inline long long read(void) {
	long long s=0;
	char ch=getchar();
	while(!id(ch)) ch=getchar();
	while(id(ch)) s=(s<<1)+(s<<3)+(ch^48),ch=getchar();
	return s;
}
const long long MAXN=1e6+10;
long long n,z[MAXN],f[MAXN][3],vis[MAXN],ans,fa[MAXN],h,vs;
vector<long long>G[MAXN];
void dfs(const long long k) {
	vis[k]=++vs;
	for(long long i=0;i<G[k].size();i++) {
		long long to=G[k][i];
		if(!vis[to]) fa[to]=k,dfs(to);
		else {
			if(vis[to]<vis[k]) continue;
			h=to;
		}
	} 
	return;
}
void dp(long long k) {
	long long tmp=0;
	for(long long i=0;i<G[k].size();i++) if(G[k][i]!=fa[k]) dp(G[k][i]);
	for(long long i=0;i<G[k].size();i++) if(G[k][i]!=fa[k]) tmp+=f[G[k][i]][0];
	f[k][1]+=tmp;
	tmp=0;
	for(long long i=0;i<G[k].size();i++) if(G[k][i]!=fa[k]) tmp+=max(f[G[k][i]][0],f[G[k][i]][1]);
	f[k][0]+=tmp;
	f[k][1]+=z[k];
	return;
}	
void wkf(long long k) {
	for(long long i=0;i<G[k].size();i++) if(G[k][i]!=fa[k]) fa[G[k][i]]=k,wkf(G[k][i]);
	return;
}
long long work(long long k) {
	h=0;
	dfs(k);
	long long hh=fa[h],tmpans=0;
	for(long long i=0;i<G[h].size();i++) if(G[h][i]==hh) G[h][i]=0;
	for(long long i=0;i<G[hh].size();i++) if(G[hh][i]==h) G[hh][i]=0;
	memset(fa,0,sizeof(fa));
	wkf(k);
	//case:1
	f[h][1]=-214748364747;
	dp(k);
	tmpans=max(max(f[k][1],f[k][0]),tmpans);
	//case:2
	memset(f,0,sizeof(f));
	f[hh][1]=-214748364747;	
	dp(k);
	tmpans=max(max(f[k][1],f[k][0]),tmpans);
}
int main() {
	n=read();
	for(long long i=1,v;i<=n;i++) z[i]=read(),v=read(),G[i].push_back(v),G[v].push_back(i);
	for(long long i=1;i<=n;i++) if(!vis[i]) ans+=work(i);
	printf("%lld",ans);
	return 0;
}
2020/8/20 12:58
加载中...