首页 > 其他分享 >luogu P1543 [POI2004] SZP 题解

luogu P1543 [POI2004] SZP 题解

时间:2024-03-30 17:22:17浏览次数:20  
标签:2000010 外向 int 题解 luogu cnt fa max SZP

题目传送门

前置知识

树形 DP

解法

将 \(a_{i}\) 向 \(i\) 连一条有向边,这样就形成了基环外向树森林。

基环外向树森林内每棵基环外向树是相互独立的,需要单独处理。

对于每棵基环外向树,任取环上一点 \(x\),断开 \(x\) 到 \(fa_{x}\) 的有向边,外向树就变成了一棵以 \(x\) 为根的树。

设 \(f_{x,0/1}\) 表示 \(x\) 不选/选时,以 \(x\) 为根的子树的最多选择个数,状态转移方程为 \(\begin{cases} f_{x,0}=\sum\limits_{y \in Son(x)} \max(f_{y,0},f_{y,1}) \\ f_{x,1}=1+\max\limits_{y \in Son(x)} \{ f_{y,0}+\sum\limits_{z \in Son(x),z \ne y} \max(f_{z,0},f_{z,1}) \}=1+f_{x,0}- \min\limits_{y \in Son(x)} \{ \max(f_{y,0},f_{y,1})-f_{y,0} \} \end{cases}\)。

将原问题拆成两部分。第一部分为 \(x\) 不限制 \(fa_{x}\),断开 \(x\) 到 \(fa_{x}\) 的有向边,在以 \(x\) 为根的树上进行 DP,得到的结果为 \(\max(f_{x,0},f_{x,1})\);第二部分为 \(x\) 限制 \(fa_{x}\)。故再次以 \(fa_{x}\) 为根进行 DP,得到的结果为 \(f_{fa_{x},1}\)。这两部分合起来能够覆盖整个问题,故二者取 \(\max\) 即可。

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long 
#define ull unsigned long long
#define sort stable_sort 
#define endl '\n'     	
struct node
{
    int nxt,to;
}e[2000010];
int head[2000010],vis[2000010],u[2000010],v[2000010],f[2000010][2],rt,cnt=0;
void add(int u,int v)
{
    cnt++;
    e[cnt].nxt=head[u];
    e[cnt].to=v;
    head[u]=cnt;
}
int dfs_huan(int x)
{
    vis[x]=1;
    return (vis[u[x]]==1)?x:dfs_huan(u[x]);
}
void dfs(int x)
{
    int minn=0x3f3f3f3f;
    vis[x]=1;
    f[x][0]=0;
    for(int i=head[x];i!=0;i=e[i].nxt)
    {
        if(e[i].to==rt)
        {
            f[e[i].to][1]=-0x3f3f3f3f;
        }
        else
        {
            dfs(e[i].to);
            f[x][0]+=max(f[e[i].to][0],f[e[i].to][1]);
            minn=min(minn,max(f[e[i].to][0],f[e[i].to][1])-f[e[i].to][0]);
        }
    }
    f[x][1]=1+f[x][0]-minn;
}
int main()
{
    int n,ans=0,maxx,i;
    cin>>n;
    for(i=1;i<=n;i++)
    {
        v[i]=i;
        cin>>u[i];
        add(u[i],v[i]);
    }
    for(i=1;i<=n;i++)
    {
        if(vis[i]==0)
        {
            rt=dfs_huan(i);
            dfs(rt);
            maxx=max(f[rt][0],f[rt][1]);
            rt=u[rt];
            dfs(rt);
            ans+=max(maxx,f[rt][1]);
        }
    }
    cout<<ans<<endl;
    return 0;
}

标签:2000010,外向,int,题解,luogu,cnt,fa,max,SZP
From: https://www.cnblogs.com/The-Shadow-Dragon/p/18105768

相关文章

  • Enumerating Rational Numbers 题解
    EnumeratingRationalNumbers题解先下结论,这道题是一道欧拉函数板子题观察题面可以发现,生成的分数有如下特性:分数都是最简分数分母与分子互质,且分子$\le$分母当然第一个除外,那个特判即可,不用纳入考虑范围我们知道,对于任意正整数n,欧拉函数,即\(\varphi(n)\)是小......
  • 题解 CF698C【LRU】
    题解CF698C【LRU】题目描述有\(n\)种物品和大小为\(k\)的队列。每次操作,以\(p_i\)的概率选择第\(i\)种物品放入队尾,如果已经有物品\(i\)了就将物品\(i\)拿出来扔到队尾。若队列大小\(\gtk\),弹出队首。求\(10^{100}\)次操作后每种物品在队列里的概率。\(1\leq......
  • upload-labs简单题解
    upload-labs详解1-19关通关全解(最全最详细一看就会)-CSDN博客Upload-labs1-21关靶场通关笔记(含代码审计)_upload-labs21关-CSDN博客搭建upload-labs环境参考文章渗透测试——upload-labs环境部署_upload-loadsphpstudy-CSDN博客文件上传浅谈-CSDN博客 Pass-01考点:J......
  • 题解 ARC175C【Jumping Through Intervals】
    先不考虑构造字典序最小的方案,只考虑求出最小的\(\sum\limits_{i=1}^{N-1}|A_{i+1}-A_i|\)。设定义域为\([L_i,R_i]\)的函数\(F_i(x)\)表示考虑后缀\([i,N]\),令\(A_i=x\)时上式最小的值。初值为\(F_N(x)=0,(x\in[L_N,R_N])\)。显然有转移方程:\[F_i(x)=\min\limits_{y......
  • 题解 CF70E【Information Reform】
    题解CF70E【InformationReform】题目描述\(n\)个点的树,边权为\(1\)。可以花费常数\(k\),在一个点上建基站。每个点\(i\)需要找到离他最近的基站\(a_i\),花费\(d[dis(i,a_i)]\)。一种方案的总花费是建基站的花费加上每个点的花费之和。最小化总花费。输出方案\(a_i\)。......
  • ICPC2023 陕西邀请赛 题解
    G-PermutationQuestion找到一个排列\(p\),使得\(\prod_{i=1}^nlcm(p_i,p_{(imodn)+1})\)最大Solution考虑到\(x\)和\(x-1\)必然是互质的所以顺序排列即可Code#include<bits/stdc++.h>usingnamespacestd;intmain(){intn;cin>>n;for(inti......
  • 快递员的烦恼【华为OD机试JAVA&Python&C++&JS题解】
    一.题目-快递员的烦恼快递公司每日早晨,给每位快递员推送需要送到客户手中的快递以及路线信息,快递员自己又查找了一些客户与客户之间的路线距离信息,请你依据这些信息,给快递员设计一条最短路径,告诉他最短路径的距离。注意:不限制快递包裹送到客户手中的顺序,但必须保证都送......
  • 园区参观路径【华为OD机试JAVA&Python&C++&JS题解】
    一.题目-园区参观路径园区某部门举办了FamilyDay,邀请员工及其家属参加;将公司园区视为一个矩形,起始园区设置在左上角,终点园区设置在右下角;家属参观园区时,只能向右和向下园区前进;求从起始园区到终点园区会有多少条不同的参观路径;输入描述:第一行为园区长和宽;后面每一行表示......
  • [题解]P1439 【模板】最长公共子序列
    P1439【模板】最长公共子序列题意简述给出\(1,2,…,n\)的两个排列\(P_1\)和\(P_2\),求它们的最长公共子序列。范围限制:\(n\le10^5\)。样例53214512345输出:3。思路简述这道题看似是最长公共子序列,但是发现如果用\(O(n^2)\)的复杂度实现\(LCS\)就会时......
  • 2024年03月CCF-GESP编程能力等级认证C++编程八级真题解析
    本文收录于专栏《C++等级认证CCF-GESP真题解析》,专栏总目录:点这里。订阅后可阅读专栏内所有文章。一、单选题(每题2分,共30分)第1题为丰富食堂菜谱,炒菜部进行头脑风暴。肉类有鸡肉、牛肉、羊肉、猪肉4种,切法有肉排、肉块、肉末3种,配菜有圆白菜、油菜、豆腐3种,辣度有......