在做这道题之前,可以先去看一下:
P1453 城市环路: https://www.cnblogs.com/liyishui2003/p/16150985.html
如果说城市环路是没有上司的舞会的基环树版本
那P2607就是城市环路的基环树森林版本
刚开始开开心心把城市环路的代码改了改输出输入就交了,wa,20tps
挠头,想了想,唉,它没有保证联通哎!那就是一片基环树森林,再加一个col数组表示有没有被查过就好了
注意:这种求和,累加的题目,不开longlong..就..
#include<bits/stdc++.h> using namespace std; const int maxn=int(1e6)+7; int col[maxn],vis[maxn],vis2[maxn],n,p[maxn],head[maxn],cnt=0,s,t,isfind=0,tree=0; long long finalans=0,ans=0,dp[maxn][3]; double k; struct lys{ int from,to,nxt; }e[maxn*3]; void add(int from,int to) { cnt++;e[cnt].from=from;e[cnt].to=to;e[cnt].nxt=head[from];head[from]=cnt; } void build(int u,int fa) { col[u]=tree; vis[u]=1; for(int i=head[u];i;i=e[i].nxt) { int to=e[i].to; if(to==fa) continue; if(vis[to]==1) { s=to;t=u;continue; } build(to,u); } } void dfs(int fa,int u) { vis[u]=1; dp[u][0]=0; dp[u][1]=p[u]; for(int i=head[u];i;i=e[i].nxt) { int to=e[i].to; if(to==fa||vis[to]) continue; dfs(u,to); dp[u][0]+=max(dp[to][0],dp[to][1]); dp[u][1]+=dp[to][0]; } } int main() { //freopen("lys.in","r",stdin); cin>>n; for(int i=1;i<=n;i++) {int v; cin>>p[i]>>v; add(i,v); add(v,i); } for(int i=1;i<=n;i++) { if(!col[i]) { tree++; ans=0; memset(vis,0,sizeof(vis)); build(i,-1); memset(vis,0,sizeof(vis)); dfs(-1,s); ans=dp[s][0]; memset(vis,0,sizeof(vis)); dfs(-1,t); ans=max(ans,dp[t][0]); finalans+=ans; } } printf("%lld",finalans); }