ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

391 基环树 P2607 [ZJOI2008] 骑士

2022-07-11 00:04:54  阅读:126  来源: 互联网

标签:rt return int LL P2607 ne 基环树 391 include


视频链接:

// Luogu P2607 [ZJOI2008] 骑士
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=1e6+10;
typedef long long LL;
int n;
struct edge{int v,ne;}e[N];
int h[N],w[N],idx;
int r1,r2,vis[N];
LL f[N][2],sum;

void add(int a,int b){
  e[++idx]={b,h[a]};
  h[a]=idx;
}
void find(int u,int rt){//找两个根
  vis[u]=1;
  for(int i=h[u];i;i=e[i].ne){
    int v=e[i].v;
    if(v==rt){r1=u,r2=v;return;}
    if(vis[v])continue;
    find(v,rt);
  }
}
LL dfs(int u,int rt){//树上DP
  f[u][0]=0; f[u][1]=w[u];
  for(int i=h[u];i;i=e[i].ne){
    int v=e[i].v;
    if(v==rt)continue;
    dfs(v,rt);
    f[u][0]+=max(f[v][0],f[v][1]);
    f[u][1]+=f[v][0];
  }
  return f[u][0];
}
int main(){
  scanf("%d",&n);
  for(int v=1,u;v<=n;v++){
    scanf("%d%d",&w[v],&u);
    add(u,v);//单向边
  }
  for(int i=1;i<=n;i++){
    if(!vis[i]){
      r1=r2=0;
      find(i,i);
      if(r1){
        LL res1=dfs(r1,r1);
        LL res2=dfs(r2,r2);
        sum+=max(res1,res2);
      }
    }
  }
  printf("%lld",sum);
  return 0;
}
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
const int N=1e6+10;
int n;
struct edge{int v,ne;}e[N<<1];
int h[N],w[N],idx;
int fa[N]; //并查集的根数组
LL f[N][2],sum;
vector<PII> roots;

void add(int a,int b){
  e[++idx]={b,h[a]};
  h[a]=idx;
}
int find(int x){
  if(fa[x]==x)return x;
  return fa[x]=find(fa[x]);
}
LL dfs(int u,int fa){//树上DP
  f[u][0]=0; f[u][1]=w[u];
  for(int i=h[u];i;i=e[i].ne){
    int v=e[i].v;
    if(v==fa)continue;
    dfs(v,u);
    f[u][0]+=max(f[v][0],f[v][1]);
    f[u][1]+=f[v][0];
  }
  return f[u][0];
}
int main(){
  scanf("%d",&n);
  for(int i=1;i<=n;i++) fa[i]=i;
  for(int i=1,x;i<=n;i++){
    scanf("%d%d",&w[i],&x);
    int pa=find(i),pb=find(x);
    if(pa!=pb){
      fa[pa]=pb;//合并
      add(i,x),add(x,i);//加边
    }
    else
      roots.push_back({x,i});//存根
  }
  for(auto t:roots){
    int a=t.first,b=t.second;
    sum+=max(dfs(a,-1),dfs(b,-1));
  }
  printf("%lld",sum);
  return 0;
}

 

标签:rt,return,int,LL,P2607,ne,基环树,391,include
来源: https://www.cnblogs.com/dx123/p/16464427.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有