[JZOJ] 5905. 黑暗之魂(darksoul)

本文深入探讨了基环树直径问题的算法解决方案,通过在子树和环上进行动态规划,利用单调队列优化复杂度至O(n),并详细介绍了实现过程中的关键步骤和技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

基环树直径裸题

分别在子树做DP,环上做DP,环上可以用单调队列优化到\(O(n)\)

写起来很麻烦

#include<algorithm>
#include<iostream>
#include<cstdio>
#define int long long
using namespace std;

inline int rd(){
    int ret=0,f=1;char c;
    while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;
    while(isdigit(c))ret=ret*10+c-'0',c=getchar();
    return ret*f;
}
#define pc putchar
#define space() pc(' ')
#define nextline() pc('\n')
void pot(int x){if(!x)return;pot(x/10);pc('0'+x%10);}
void out(int x){if(!x)pc('0');if(x<0)pc('-'),x=-x;pot(x);}

const int MOD = 1e9+7;

inline void upmax(int &x,int y){x=max(x,y);}
inline void upmin(int &x,int y){x=min(x,y);}

int add(int x,int y){return x+y>MOD?x+y-MOD:x+y;}
int sub(int x,int y){return x-y<0?x-y+MOD:x-y;}
int mul(int x,int y){return (long long)(1ll*x*y)%MOD;}
void Add(int &x,int y){x=add(x,y);}
void Sub(int &x,int y){x=sub(x,y);}
void Mul(int &x,int y){x=mul(x,y);}

const int MAXN = 1000005;
const int M = MAXN<<1;

int n;
int nex[M],to[M],wi[M];
int head[MAXN],ecnt=1;
inline void adde(int x,int y,int w){
    nex[++ecnt] = head[x];
    to[ecnt] = y;
    wi[ecnt] = w;
    head[x] = ecnt;
}
int cir[MAXN],vis[MAXN],lenc;

int dfn[MAXN],low[MAXN],tim;
int sta[MAXN],ins[MAXN],top;
void tarjan(int x,int frm){
    dfn[x]=low[x]=++tim;
    ins[sta[++top]=x]=1;
    for(int i=head[x];i;i=nex[i]){
        if(i==(frm^1)||i==frm)continue;
        int v=to[i];
        if(!dfn[v]){
            tarjan(v,i);
            upmin(low[x],low[v]);   
        }else if(ins[v]){
            upmin(low[x],dfn[v]);   
        }
    }
    if(dfn[x]!=low[x]) return;
    if(lenc>2) return;
    int elm;
    do{
        elm=sta[top--];
        ins[elm]=0;
        cir[++lenc]=elm;    
    }while(elm!=x);
    if(lenc<=2) lenc=0;
}
int ans;
int f[MAXN],g[MAXN],h[MAXN];
void dfs(int x,int pre){
    for(int i=head[x];i;i=nex[i]){
        int v=to[i];
        if(v==pre||vis[v]) continue;
        dfs(v,x);
        upmax(ans,f[x]+f[v]+wi[i]);
        upmax(f[x],f[v]+wi[i]); 
    }
}

int dis[MAXN];
void dfs2(int x){
    for(int i=head[cir[x]];i;i=nex[i]){
        int v=to[i];
        if(v!=cir[x+1])continue;
        dis[x]=wi[i];
        dfs2(x+1);
    }
}
void gfs(int x,int pre){
//  vis[x]=1;
    for(int i=head[x];i;i=nex[i]){
        int v=to[i];
        if(v==pre) continue;
        gfs(v,x);
        upmax(ans,f[x]+f[v]+wi[i]);
        upmax(f[x],f[v]+wi[i]); 
    }
}

int q[MAXN*2],hd=1,tl; 
signed main(){
    freopen("darksoul8.in","r",stdin);
    freopen("darksoul.out","w",stdout);
    n=rd();
    int x,y,w;
    for(int i=1;i<=n;i++){
        x=rd();y=rd();w=rd();
        if(x==y) continue;
        adde(x,y,w);adde(y,x,w);
    }
    for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i,0);
    for(int i=1;i<=lenc;i++) vis[cir[i]]=1;
    for(int i=1;i<=lenc;i++) dfs(cir[i],0);
    cir[lenc+1]=cir[1];
    dfs2(1);
    for(int i=1;i<=lenc;i++) g[i]=g[i+lenc]=f[cir[i]],dis[i+lenc]=dis[i];
    dis[0]=dis[lenc]; dis[2*lenc+1]=dis[1]; 
    int sumc=0;
    for(int i=1;i<=lenc;i++) sumc+=dis[i]; 
    for(int i=1;i<=lenc*2;i++) dis[i]+=dis[i-1];
    int j=1;
    while(dis[lenc]-dis[j-1]>sumc/2) j++;
    for(int k=j;k<=lenc;k++){
        while(hd<=tl&&g[q[tl]]-dis[q[tl]-1]<=g[k]-dis[k-1]) tl--;
        q[++tl]=k;  
    }
    for(int i=lenc+1;i<=lenc*2;i++){
        while(hd<=tl&&dis[i-1]-dis[q[hd]-1]>sumc/2) hd++;
        h[i]=g[q[hd]]-dis[q[hd]-1]+g[i]+dis[i-1];
        while(hd<=tl&&g[q[tl]]-dis[q[tl]-1]<=g[i]-dis[i-1]) tl--;
        q[++tl]=i;
    }
    for(int i=lenc+1;i<=lenc*2;i++) upmax(ans,h[i]);
    out(ans+1);
    return 0;
}

转载于:https://www.cnblogs.com/ghostcai/p/9883313.html

基于C2000 DSP的电力电子、电机驱动和数字滤波器的仿真模型构建及其C代码实现方法。首先,在MATLAB/Simulink环境中创建电力电子系统的仿真模型,如三相逆变器,重点讨论了PWM生成模块中死区时间的设置及其对输出波形的影响。接着,深入探讨了C2000 DSP内部各关键模块(如ADC、DAC、PWM定时器)的具体配置步骤,特别是EPWM模块采用上下计数模式以确保对称波形的生成。此外,还讲解了数字滤波器的设计流程,从MATLAB中的参数设定到最终转换为适用于嵌入式系统的高效C代码。文中强调了硬件在环(HIL)和支持快速原型设计(RCP)的重要性,并分享了一些实际项目中常见的陷阱及解决方案,如PCB布局不当导致的ADC采样异常等问题。最后,针对中断服务程序(ISR)提出了优化建议,避免因ISR执行时间过长而引起的系统不稳定现象。 适合人群:从事电力电子、电机控制系统开发的技术人员,尤其是那些希望深入了解C2000 DSP应用细节的研发工程师。 使用场景及目标:①掌握利用MATLAB/Simulink进行电力电子设备仿真的技巧;②学会正确配置C2000 DSP的各项外设资源;③能够独立完成从理论设计到实际产品落地全过程中的各个环节,包括但不限于数字滤波器设计、PWM信号生成、ADC采样同步等。 其他说明:文中提供了大量实用的代码片段和技术提示,帮助读者更好地理解和实践相关知识点。同时,也提到了一些常见错误案例,有助于开发者规避潜在风险。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值