cf555e

cf555e(缩点)

给一个 n 个点 m 条边的图,以及 q 对点 (s,t),让你给 m 条边定向。问是否存在一种方案,使每对点的 s 能走到 t。 \(n,m,q≤ 2×10^5\).

首先,在一个边双内,一定存在一种定向方案,使得边双内点两两可达。(考虑桥)

因此,可以直接把边双缩点。然后树上差分看看有没有冲突即可。

注意rmq-st求lca用的是欧拉序!

#include <cstdio>
#include <functional>
#include <algorithm>
using namespace std;

typedef pair<int, int> pi;
#define mp make_pair
const int maxn=2e5+5;
int n, m, q;

struct Edge{
    int fr, to, nxt;
}e1[maxn*2], e2[maxn*2];
int fir1[maxn], fir2[maxn], cnte1=1, cnte2=0;
void addedge(int x, int y, Edge *e, int *fir, int &cnte){
    Edge &ed=e[++cnte]; ed.fr=x;
    ed.to=y; ed.nxt=fir[x]; fir[x]=cnte; }

int tim, dfn[maxn], low[maxn], st[maxn], tl, cntgp, gp[maxn];
void tarjan(int u, int pe, Edge *e, int *fir){ int v;
    dfn[u]=low[u]=++tim; st[++tl]=u;
    for (int i=fir[u]; i; i=e[i].nxt){
        v=e[i].to; if (i==pe) continue; //对于求桥只能保存父边 
        if (dfn[v]){ low[u]=min(low[u], dfn[v]); continue; }
        tarjan(v, i^1, e, fir); low[u]=min(low[u], low[v]);
    }
    if (dfn[u]!=low[u]) return;
    ++cntgp;
    while (dfn[st[tl]]!=low[st[tl]]) gp[st[tl--]]=cntgp;
    gp[st[tl--]]=cntgp;
}

int block[maxn], cntb, dep[maxn], ftim[maxn], f[maxn*2][19], rt[maxn];
void st_dfs(int u, int p, Edge *e, int *fir){ int v;
    block[u]=cntb; dep[u]=dep[p]+1; ftim[u]=++tim; f[tim][0]=u;
    for (int i=fir[u]; i; i=e[i].nxt){
        v=e[i].to; if (v==p) continue;
        st_dfs(v, u, e, fir); 
        f[++tim][0]=u;  //必须放在这里!!至于为什么,想想菊花(树) 
    }
}

int up[maxn], down[maxn];  //标记类型:立即生效,而不是处理后生效 

int getlca(int x, int y){  //注意如果x>y要swap 
    x=ftim[x]; y=ftim[y]; 
    if (x>y) swap(x, y); int c=-1;
    for (int l=y-x+1; l; l>>=1) ++c;
    if (dep[f[x][c]]<dep[f[y-(1<<c)+1][c]]) return f[x][c];
    else return f[y-(1<<c)+1][c];
}

bool ans=true;
pi dfs(int u, int p, Edge *e, int *fir){
    pi upi=mp(up[u], down[u]), tmp;
    for (int i=fir[u]; i; i=e[i].nxt){
        if (e[i].to==p) continue;
        tmp=dfs(e[i].to, u, e, fir);
        upi.first+=tmp.first; upi.second+=tmp.second;
    }
    if (upi.first&&upi.second) ans=false;
    return upi;
}

int main(){
    scanf("%d%d%d", &n, &m, &q); int x, y, lca;
    for (int i=1; i<=m; ++i){
        scanf("%d%d", &x, &y); 
        addedge(x, y, e1, fir1, cnte1); 
        addedge(y, x, e1, fir1, cnte1); }
    for (int i=1; i<=n; ++i) if (!dfn[i]) tarjan(i, 0, e1, fir1);
    int g1, g2; tim=0;
    for (int i=2; i<=cnte1; ++i)
        if ((g1=gp[e1[i].fr])!=(g2=gp[e1[i].to]))
            addedge(g1, g2, e2, fir2, cnte2);
    for (int i=1; i<=cntgp; ++i) 
        if (!dep[i]) ++cntb, rt[i]=1, st_dfs(i, 0, e2, fir2);
    for (int i=1; i<19; ++i)    
        for (int j=1; j<=tim; ++j){
            if (j+(1<<i-1)>tim){ f[j][i]=f[j][i-1]; continue; }
            if (dep[f[j][i-1]]<dep[f[j+(1<<i-1)][i-1]]) 
            f[j][i]=f[j][i-1]; else f[j][i]=f[j+(1<<i-1)][i-1];
        }
    for (int i=1; i<=q; ++i){
        scanf("%d%d", &x, &y); x=gp[x]; y=gp[y]; lca=getlca(x, y);
        if (block[x]!=block[y]){ puts("No"); return 0; }
        up[x]+=1; up[lca]+=-1; down[y]+=1; down[lca]+=-1;
    }
    for (int i=1; i<=cntgp; ++i) 
        if (rt[i]) dfs(i, 0, e2, fir2); 
    puts(ans?"Yes":"No");
    return 0;
}

转载于:https://www.cnblogs.com/MyNameIsPc/p/9574939.html

【四轴飞行器】非线性三自由度四轴飞行器模拟器研究(Matlab代码实现)内容概要:本文围绕非线性三自由度四轴飞行器模拟器的研究展开,重点介绍基于Matlab代码实现的四轴飞行器动力学建模与仿真方法。研究构建了考虑非线性特性的飞行器数学模型,涵盖姿态动力学与运动学方程,实现了三自由度(滚转、俯仰、偏航)的精确模拟。文中详细阐述了系统建模过程、控制算法设计思路及仿真结果分析,帮助读者深入理解四轴飞行器的飞行动力学特性与控制机制;同时,该模拟器可用于算法验证、控制器设计与教学实验。; 适合人群:具备一定自动控制理论基础和Matlab编程能力的高校学生、科研人员及无人机相关领域的工程技术人员,尤其适合从事飞行器建模、控制算法开发的研究生和初级研究人员。; 使用场景及目标:①用于四轴飞行器非线性动力学特性的学习与仿真验证;②作为控制器(如PID、LQR、MPC等)设计与测试的仿真平台;③支持无人机控制系统教学与科研项目开发,提升对姿态控制与系统仿真的理解。; 阅读建议:建议读者结合Matlab代码逐模块分析,重点关注动力学方程的推导与实现方式,动手运行并调试仿真程序,以加深对飞行器姿态控制过程的理解。同时可扩展为六自由度模型或加入外部干扰以增强仿真真实性。
基于分布式模型预测控制DMPC的多智能体点对点过渡轨迹生成研究(Matlab代码实现)内容概要:本文围绕“基于分布式模型预测控制(DMPC)的多智能体点对点过渡轨迹生成研究”展开,重点介绍如何利用DMPC方法实现多智能体系统在复杂环境下的协同轨迹规划与控制。文中结合Matlab代码实现,详细阐述了DMPC的基本原理、数学建模过程以及在多智能体系统中的具体应用,涵盖点对点转移、避障处理、状态约束与通信拓扑等关键技术环节。研究强调算法的分布式特性,提升系统的可扩展性与鲁棒性,适用于多无人机、无人车编队等场景。同时,文档列举了大量相关科研方向与代码资源,展示了DMPC在路径规划、协同控制、电力系统、信号处理等多领域的广泛应用。; 适合人群:具备一定自动化、控制理论或机器人学基础的研究生、科研人员及从事智能系统开发的工程技术人员;熟悉Matlab/Simulink仿真环境,对多智能体协同控制、优化算法有一定兴趣或研究需求的人员。; 使用场景及目标:①用于多智能体系统的轨迹生成与协同控制研究,如无人机集群、无人驾驶车队等;②作为DMPC算法学习与仿真实践的参考资料,帮助理解分布式优化与模型预测控制的结合机制;③支撑科研论文复现、毕业设计或项目开发中的算法验证与性能对比。; 阅读建议:建议读者结合提供的Matlab代码进行实践操作,重点关注DMPC的优化建模、约束处理与信息交互机制;按文档结构逐步学习,同时参考文中提及的路径规划、协同控制等相关案例,加深对分布式控制系统的整体理解。
07-24
CF1583E 是 Codeforces 平台上的一道编程竞赛题目,题目标题为 "Cesium",属于 Codeforces Round #760 (Div. 3) 的一部分。这道题目的核心是构造一个满足特定条件的排列(permutation),并且要求选手能够处理不同情况下的构造逻辑。 题目大意是给定一个长度为 $ n $ 的排列 $ p $,要求构造一个排列,使得对于每个位置 $ i $,其值 $ p_i $ 满足以下条件之一: - $ p_i = i $ - $ p_i = i + 1 $ - $ p_i = i - 1 $ 换句话说,每个元素必须与其索引值相邻(包括等于自身索引的情况)。如果无法构造这样的排列,则输出 `-1`。 解题的关键在于理解哪些 $ n $ 值可以构造出满足条件的排列,并找出构造策略。通过分析,可以发现: - 当 $ n \equiv 2 \mod 3 $ 时,无法构造出满足条件的排列。 - 构造方法通常采用分块策略,例如将排列按照 2、1、3 的模式循环构造,例如 $ [2, 1, 3] $,$ [2, 1, 3, 4] $,等等,以确保每个元素都满足条件[^1]。 以下是一个 Python 实现的示例代码,用于判断是否可以构造满足条件的排列,并输出结果: ```python def solve(n): if n % 3 == 2: print(-1) return res = [] for i in range(1, n + 1, 3): if i + 1 <= n: res.append(i + 1) res.append(i) else: res.append(i) if i + 2 <= n: res.append(i + 2) print(' '.join(map(str, res))) # 示例输入 solve(5) # 输出示例:2 1 3 5 4 ``` 在上述代码中,构造逻辑基于每三个连续的数字,将中间的两个数字交换位置,同时保留第三个数字。这样可以确保所有元素都满足题目要求。 ### 相关问题 1. 如何判断一个排列是否满足 CF1583E 的构造条件? 2. 为什么当 $ n \equiv 2 \mod 3 $ 时无法构造满足条件的排列? 3. CF1583E 的构造策略是否唯一?是否存在其他构造方法? 4. 如何调整 CF1583E 的构造逻辑以适应不同的排列长度? 5. 在编程竞赛中,如何快速识别类似 CF1583E 的构造问题并设计解决方案?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值