1 条题解

  • 0
    @ 2025-8-24 22:52:40

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar wangshi
    能赢吗?会赢的!

    搬运于2025-08-24 22:52:40,当前版本为作者最后更新于2024-09-18 09:25:39,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    模拟赛遇到这个题,写题解记录一下。

    首先,因为每天一开始怪会先加 BB ,因此我们对于 i2i \ge 2wiw_i 直接设置为 wi+Bw_i+B

    然后,分两种情况讨论。

    • ABA \leq B

      tit_i 为到达 ii 最晚时间。

      对于 w1wiw_1 \leq w_i ,显然永远也到达不了 ii , tit_i 直接设为 00

      对于 w1>wiw_1 > w_i ,有式子 w1+A(i1)>wi+B(i1)w_1+A(i-1) > w_i+B(i-1) ,移项得 i<w1wiBAi < \frac{w_1-w_i}{B-A} ,因此 ti=w1wi1BAt_i = \frac{w_1-w_i-1}{B-A} ,对于 A=BA=B 特殊判一下。

    • A>BA > B

      tit_i 为到达 ii 最早时间。

      对于 w1>wiw_1>w_iti=1t_i=1

      对于 w1wiw_1 \leq w_i ,同样用上面的式子可以推出 ti=wiw1BA+2t_i = \frac{w_i-w_1}{B-A}+2

    对两种情况分别跑最短路即可,可能有一些细节吧。

    #include<bits/stdc++.h>
    #define int long long
    #define fi first
    #define se second
    #define wang_shi return 0
    using namespace std;
    const int N=1e6+10;
    typedef pair<int,int> PII;
    int n,m,A,B,dis[N],vis[N],w[N],t[N];
    vector<int> g[N];
    void Solve1()
    {
    	for(int i=2;i<=n;++i)
    	{
    		if(A==B) t[i]=(w[1]>w[i]?1e18:0);
    		else t[i]=(w[1]>w[i]?(w[1]-w[i]-1)/(B-A)+1:0);
    		dis[i]=-1;
    	}	
    	queue<int> q; q.push(1);
    	while(!q.empty())
    	{
    		int u=q.front(); q.pop();
    		for(int v:g[u])
    		{
    			if(dis[v]==-1&&dis[u]+1<=t[v])
    			{
    				dis[v]=dis[u]+1;
    				q.push(v);
    			}
    		}
    	}
    	cout<<dis[n]<<'\n'; 
    }
    void Solve2()
    {
    	for(int i=2;i<=n;++i)
    	{
    		t[i]=(w[1]>w[i]?1:(w[i]-w[1])/(A-B)+2);
    		dis[i]=1e18;
    	}
    	priority_queue<PII,vector<PII>,greater<PII>> q;
    	q.push({0,1}); int sum=0;
    	while(!q.empty())
    	{
    		int u=q.top().se; q.pop();
    		if(vis[u]) continue;
    		if(sum<dis[u]){dis[u]=1e18;continue;}
    		sum++;
    		for(int v:g[u])
    		{
    			if(max(dis[u]+1,t[v])<dis[v])
    			{
    				dis[v]=max(dis[u]+1,t[v]);
    				q.push({dis[v],v});
    			}
    		}
    	}
    	cout<<(dis[n]==1e18?-1:dis[n])<<'\n';
    } 
    void Solve()
    {
    	cin>>n>>m>>A>>B;
    	for(int i=1;i<=m;++i) 
    	{
    		int u,v; cin>>u>>v;
    		g[u].push_back(v);
    		g[v].push_back(u);
    	}
    	for(int i=1;i<=n;++i)
    	{
    		cin>>w[i];
    		w[i]+=(i==1?0:B);
    	}
    	if(A<=B) Solve1();
    	else Solve2();
    	for(int i=1;i<=n;++i)
    	{
    		w[i]=t[i]=dis[i]=vis[i]=0;
    		g[i].clear();
    	}	
    }
    signed main()
    {
    	ios::sync_with_stdio(0); cin.tie(0);
    	int t=1; cin>>t;
    	while(t--) Solve();
    	wang_shi;
    }
    
    • 1

    信息

    ID
    9391
    时间
    3000ms
    内存
    1024MiB
    难度
    5
    标签
    递交数
    0
    已通过
    0
    上传者