hdu 6071

来源:互联网 发布:混乱中立 知乎 编辑:程序博客网 时间:2024/06/06 13:16

存一个代码……

题目很好理解,就是阳光长跑规则,为了偷懒想要最短路,只不过被限制在了从体院馆出发并且在体育馆结束

我好蠢真的,我原先只想到每条路可以来回跑,没想到利用一条路的性质
比赛的时候最小公倍数这种东西都在想了……简直nc

果然是题目做的不够多
题解:地址


这里写图片描述


扣了半天脚看懂了这个题解
因为1-2或者2-3必有一条是必须要跑的,所以就把他们作为取模的基础,就可以通过取出不同的模造出不同花样的路,其他路的不同长度特性也可以充分利用到

(然后按照我自己原先的思路,是任意选一条路作为来回跑基准,但要保证经过,然后就搞得很复杂,我果然蠢的没药了)


参照blog:http://blog.csdn.net/clx55555/article/details/76692816

这里的最短路vis状态因为路径的更新要不断更改(应该是这个意思吧)


#include <cmath>#include <iostream>#include <cstdio>#include <vector>#include <string>#include <cstring>#include <map>#include <queue>#include <algorithm>#include <stack>using namespace std;typedef long long LL;#define N 1000005typedef __int64 I64;const I64 INF=0x3f3f3f3f3f3f3f3f;struct points{    int wz;    I64 dis;    points() {}    points(int a,long long b)    {        wz=a,dis=b;    }};I64 dis[5][60000],K,ans;bool vis[5][60000];int a[5][5];int m;bool SPFA(int st){  int wz;  I64 dis_;  for (int i=0;i<4;i++)        for (int j=0;j<m;j++) { dis[i][j]=INF; vis[i][j]=false; }    dis[st][0]=0;    vis[st][0]=true;  queue<points >q;  points now;  q.push(points(st,0));  while (!q.empty())  {    now=q.front(); q.pop();    vis[now.wz][now.dis%m]=false;    for (int i=1;i<=2;i++)    {      dis_=now.dis+a[now.wz][i];      if (i==1) wz=(now.wz+1)%4; else wz=(now.wz+3)%4;      if (wz==st)      {          if (dis_<K) ans=min(ans,dis_+((K-dis_-1)/m+1)*m); else ans=min(ans,dis_);      }      if (dis[wz][dis_%m]>dis_)      {        dis[wz][dis_%m]=dis_;        if (!vis[wz][dis_%m])        {          q.push(points(wz,dis_));          vis[wz][dis_%m]=true;        }      }    }  }  return true;}int main(){    int cases,i,j;    scanf("%d",&cases);   while (cases--)   {      scanf("%lld%d%d%d%d",&K,&a[1][1],&a[2][1],&a[3][1],&a[0][1]);       m=min(a[2][1],a[1][1])*2;        a[1][2]=a[0][1];        a[2][2]=a[1][1];        a[3][2]=a[2][1];        a[0][2]=a[3][1];        ans=((K-1)/m+1)*m;        SPFA(2);       printf("%lld\n",ans);   } return 0;}
原创粉丝点击