P3403 跳楼机

题解:

据说是最短路经典题

考虑mod c一意义下

我们会发现mod c相同的话我们一定会用最少步数到达,剩余的都用c转移

由于转移图有环所以我们用spfa来dp(其实也可以理解成最短路)

wa了好多次。。。。初始距离是1不是0。。。。

代码:

#include <bits/stdc++.h>
using namespace std;
#define rint register ll
#define IL inline
#define rep(i,h,t) for (rint i=h;i<=t;i++)
#define dep(i,t,h) for (rint i=t;i>=h;i--)
#define ll long long
#define ull unsigned ll
const ll N=2e5;
ll a,b,c,l,head[N];
ull dis[N],n;
bool ft[N];
const ull INF=1ull<<63;
struct re{
  ll a,b,c;
}e[N*2];
void arr(ll x,ll y,ll z)
{
  e[++l].a=head[x];
  e[l].b=y;
  e[l].c=z;
  head[x]=l;
}
queue<ll> q; 
int main()
{
  freopen("1.in","r",stdin);
  freopen("1.out","w",stdout);
  ios::sync_with_stdio(false);
  cin>>n;
  cin>>a>>b>>c;
  rep(i,0,c) dis[i]=INF;
  dis[1]=0;
  rep(i,0,c-1)
  {
    arr(i,(a+i)%c,a);
    arr(i,(b+i)%c,b);
  }
  q.push(1);
  while (!q.empty())
  {
    ll x=q.front(); q.pop();
    for (rint u=head[x];u;u=e[u].a)
    {
      ll v=e[u].b;
      if (dis[v]>dis[x]+e[u].c)
      {
        dis[v]=dis[x]+e[u].c;
        if (!ft[v])
        {
          ft[v]=1;
          q.push(v);
        }
      }
    }
    ft[x]=0;
  }
  ull ans=0;
  rep(i,0,c-1)
  {
    dis[i]++;
    if (dis[i]<=n)
      ans+=(n-dis[i])/c+1;
    }
  cout<<ans<<endl;
  return 0;
}

猜你喜欢

转载自www.cnblogs.com/yinwuxiao/p/9638265.html
今日推荐