比赛 |
中秋节快乐! |
评测结果 |
AAAAAAAAAA |
题目名称 |
骑士 |
最终得分 |
100 |
用户昵称 |
flyfree |
运行时间 |
0.745 s |
代码语言 |
C++ |
内存使用 |
13.95 MiB |
提交时间 |
2024-09-17 09:37:04 |
显示代码纯文本
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define MAXN 1000010
inline ll read(){
ll x=0,f=1;
char c=getchar();
while(c<'0'||c>'9'){
if(c=='-')f=-1;
c=getchar();
}
while(c>='0'&&c<='9'){
x=x*10+c-'0';
c=getchar();
}
return x*f;
}
ll n,idx,cnt,fnt,tp,ansz;
ll hd[MAXN],ed[MAXN*2],nxt[MAXN*2];
ll dp[MAXN][3],rd[MAXN],val[MAXN];
ll ring_dp[MAXN][3],ring[MAXN];
bool mp[MAXN],used[MAXN];
queue <ll> q;
//std::map <ll,bool> mp,used;
//std::map <ll,ll> ring;
void build(ll x,ll y){
nxt[++idx]=hd[x];
hd[x]=idx;
ed[idx]=y;
}
void dfs(ll now,ll fa){
dp[now][1]=val[now];
for(int i=hd[now];i;i=nxt[i]){
ll y=ed[i];
if(rd[y]==2||y==fa)continue;
dfs(y,now);
dp[now][1]+=dp[y][0];
dp[now][0]+=max(dp[y][0],dp[y][1]);
}
}
void ring_dfs(ll now){
ring[++cnt]=now;
used[now]=true;
for(int i=hd[now];i;i=nxt[i]){
ll y=ed[i];
if(used[y]||!mp[y])continue;
ring_dfs(y);
}
}
void work(ll now){
ll ans=0;
cnt=0;
ring_dfs(now);
ring_dp[1][0]=dp[ring[1]][0],ring_dp[1][1]=dp[ring[1]][0];
for(int i=2;i<=cnt;i++){
ring_dp[i][0]=max(ring_dp[i-1][0],ring_dp[i-1][1])+dp[ring[i]][0];
ring_dp[i][1]=ring_dp[i-1][0]+dp[ring[i]][1];
}
ans=max(ring_dp[cnt][1],ring_dp[cnt][0]);
if(cnt>2){
ring_dp[2][0]=dp[ring[2]][0],ring_dp[2][1]=dp[ring[2]][0];
for(int i=3;i<=cnt;i++){
ring_dp[i][0]=max(ring_dp[i-1][0],ring_dp[i-1][1])+dp[ring[i]][0];
ring_dp[i][1]=ring_dp[i-1][0]+dp[ring[i]][1];
}
ans=max(ans,ring_dp[cnt][0]+dp[ring[1]][1]);
}else{
ans=max(ans,dp[ring[1]][1]+dp[ring[2]][0]);
}
ansz+=ans;
}
int main(){
freopen("bzoj_1040.in","r",stdin);
freopen("bzoj_1040.out","w",stdout);
n=read();
for(int i=1;i<=n;i++){
val[i]=read(),tp=read();
build(i,tp);
build(tp,i);
rd[i]++,rd[tp]++;
}
for(int i=1;i<=n;i++){
if(rd[i]==1)q.push(i);
}
while(!q.empty()){
ll fst=q.front();
q.pop();
for(int i=hd[fst];i;i=nxt[i]){
ll y=ed[i];
if(rd[y]>1){
rd[y]--;
if(rd[y]==1)q.push(y);
}
}
}
for(int i=1;i<=n;i++){
if(rd[i]==2){
mp[i]=true;
dfs(i,0);
}
}
for(int i=1;i<=n;i++){
if(mp[i]&&!used[i])work(i);
}
// for(int i=1;i<=cnt;i++){
// cout<<ring[i]<<" "<<dp[ring[i]][1]<<" "<<dp[ring[i]][0]<<endl;
// }
cout<<ansz;
return 0;
}