ABC273F Hammer 题解
ABC273F Hammer 题解
题目大意#
数轴上有 个锤子和 堵墙,第 个锤子位于 ,第 堵墙位于 ,第 个锤子可以对应的敲开第 堵墙。以原点为起点,给定终点 ,问最少移动多少个单位长度才能走到 。必须拿到对应锤子敲开墙才能走过这堵墙。
Solve#
考虑建图。对于一堵墙 ,对于所有必须先经过这堵墙才能到达的点 ,我们连一条从 到 的有向边,意为限制必须先经过 才能到 。然后再连一条从 到 的有向边,意义同上。处理完之后再从原点向所有点连有向边。
先离散化,再在建出来的图上跑拓扑最长路即可,每条边的边权即为两端点位置之差。
至于为什么是最长路,由于图是在一个数轴上建出来的,比较特殊,所以一个点若受到多个点的约束,那么约束它的点之间一定也有约束关系,不会相互独立,所以更长的路一定包含更短的路的状态。意会一下。
无解的情况显然是从 到 的路径上有环,即约束 的条件无法全被满足,拓排完判断一下 的入度是否被消到 即可。
Code#
#include<bits/stdc++.h>
using namespace std;
inline int read()
{
short f=1;
int x=0;
char c=getchar();
while(c<'0'||c>'9') {if(c=='-') f=-1;c=getchar();}
while(c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
}
const int N=1510,M=3010;
int n,s,t,x[N],y[N],k[M],ind[M],m;
long long f[M];
vector<int>e[M];
inline void topo()
{
queue<int>q;q.push(s);
while(!q.empty())
{
int u=q.front();q.pop();
if(u==t) break;
for(int i:e[u])
{
f[i]=max(f[i],f[u]+abs(k[i]-k[u]));
if(!--ind[i]) q.push(i);
}
}
if(ind[t]) puts("-1");
else printf("%lld",f[t]);
}
signed main()
{
n=read();t=read();m=(n<<1);
for(int i=1;i<=n;i=-~i) k[i]=x[i]=read();
for(int i=1;i<=n;i=-~i) k[i+n]=y[i]=read();
k[m+1]=0;k[m+2]=t;
sort(k+1,k+m+3);
m=unique(k+1,k+m+3)-k-1;
for(int i=1;i<=n;i=-~i)
x[i]=lower_bound(k+1,k+m+1,x[i])-k,
y[i]=lower_bound(k+1,k+m+1,y[i])-k;
t=lower_bound(k+1,k+m+1,t)-k;
s=lower_bound(k+1,k+m+1,0)-k;
for(int i=1;i<=n;i=-~i)
{
e[y[i]].push_back(x[i]);ind[x[i]]=-~ind[x[i]];
if(x[i]>s)
for(int j=x[i]+1;j<=m;j=-~j)
e[x[i]].push_back(j),ind[j]=-~ind[j];
else
for(int j=1;j<x[i];j=-~j)
e[x[i]].push_back(j),ind[j]=-~ind[j];
}
for(int i=1;i<=m;i=-~i)
if(i!=s) e[s].push_back(i),ind[i]=-~ind[i];
return topo(),0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)