洛谷 P7192 [COCI2007-2008#6] GEORGE 题解
题目简述
给定一张
题目分析
注意到 T 先生的移动顺序是一定的,所以我们可以先处理出每一个时刻 T 先生在哪一条边上。
接下来,我们考虑使用 Dijkstra 算法求最短路,设当前队首可以扩展的点为
最后答案是
代码
#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
const int N=1e3+10;
const int M=1e4+10;
int n,m,a,b,k,g,t[N],cnt,head[N],cnt2,vis1[N],E[N][N],dis[N],vis2[N][N];
pair<int,int> vis[M*1000];
priority_queue<pair<int,int>,vector<pair<int,int> >,greater<pair<int,int> > > q;
struct edge
{
int to,next,value;
}e[M*2];
inline int read()
{
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9')
{
if(ch=='-')
{
f=-1;
}
ch=getchar();
}
while(ch>='0'&&ch<='9')
{
x=(x<<1)+(x<<3)+ch-48;
ch=getchar();
}
return x*f;
}
inline void write(int x)
{
if(x<0)
{
putchar('-');
x=-x;
}
if(x>9) write(x/10);
putchar(x%10+'0');
}
void addedge(int u,int v,int w)
{
e[++cnt]={v,head[u],w};
head[u]=cnt;
}
int main()
{
n=read();
m=read();
a=read();
b=read();
k=read();
g=read();
for(int i=1;i<=g;i++)
{
t[i]=read();
}
for(int i=1;i<=m;i++)
{
int u=read();
int v=read();
int w=read();
addedge(u,v,w);
addedge(v,u,w);
E[u][v]=E[v][u]=w;
}
for(int i=1;i<=g-1;i++)
{
for(int j=1;j<=E[t[i]][t[i+1]];j++)
{
vis[++cnt2]={t[i],t[i+1]};
}
vis2[t[i]][t[i+1]]=cnt2;
}
memset(dis,0x3f,sizeof dis);
q.push({k,a});
dis[a]=k;
while(!q.empty())
{
int u=q.top().second;
q.pop();
if(vis1[u]) continue;
vis1[u]=1;
for(int i=head[u];i;i=e[i].next)
{
int v=e[i].to,w=e[i].value;
if((vis[dis[u]].first==u&&vis[dis[u]].second==v)||(vis[dis[u]].first==v&&vis[dis[u]].second==u))
{
w+=vis2[vis[dis[u]].first][vis[dis[u]].second]-dis[u];
}
if(dis[v]>dis[u]+w)
{
dis[v]=dis[u]+w;
q.push({dis[v],v});
}
}
}
write(dis[b]-k);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现