hdu6071-最短路&思维&多校4&同余-Lazy Running

来源:互联网 发布:俄罗斯黑毛子知乎 编辑:程序博客网 时间:2024/05/21 17:42

http://acm.hdu.edu.cn/showproblem.php?pid=6071
给定四个点,构成一个矩形,和他们四个点两点之间的距离。
问你从2出发,再回到2,长度大于k的最短路。。
思路:
如果从2到达某点,再回到2不到,可以移动若干个2*m(m为2和临近点的距离)。个,来得到大于k的条件。
用dij算出到达i点并且mod 2*m为j的点。(这个最短路会一直执行,直到把这个表填完。)
然后对能回到2的方案,求最小值
(如果大于k,直接算,如果小于,就加2*m).

#include<bits/stdc++.h>#define ll long longusing namespace std;const int maxn=1e5;//typedef long long ll;typedef pair<int,ll>pii;int t;struct Edge{int to;ll cos;    Edge(){};    Edge(int _a,ll _b){to=_a,cos=_b;};};vector<pii>G[6];const long long inf=2e18;ll dp[6][maxn];ll all;inline void dij(){    priority_queue<pii,vector<pii>,greater<pii> > q;    for(int i=0;i<=4;i++)        for(int j=0;j<=all;j++)            dp[i][j]=2e18;        //cout<<m<<endl;    q.push(make_pair(0LL,2));                           //d[s][0]不能赋值为0    while (!q.empty())    {       ll w=q.top().first;        int j=q.top().second;        q.pop();        if (w>dp[j][w%all]) continue;        for(int k=0;k<G[j].size();k++)        {            int y=G[j][k].first;            ll dist=w+G[j][k].second;            if (dp[y][dist%all]>dist)                   //更新的时候更新取模后对应的点            {                dp[y][dist%all]=dist;                q.push(make_pair(dist,y));            }        }    }}ll k;ll a1,b1,c1,d1;int main(){scanf("%d",&t);    while(t--){         //         for(int i=0;i<5;i++){               G[i].clear();          }          //memset(G,0,sizeof(G));          scanf("%lld%lld%lld%lld%lld",&k,&a1,&b1,&c1,&d1);          G[1].push_back(make_pair(2,a1));          G[2].push_back(make_pair(1,a1));          G[2].push_back(make_pair(3,b1));          G[3].push_back(make_pair(2,b1));          G[3].push_back(make_pair(4,c1));          G[4].push_back(make_pair(3,c1));          G[4].push_back(make_pair(1,d1));          G[1].push_back(make_pair(4,d1));          all=min(b1,a1)*2;          ll ans=2e18;          dij();         // for(int i=0;i<=100;i++)            //cout<<dp[2][i]<<endl;          //cout<<dp[2][165]<<endl;          for(int i=0;i<all;i++){               ll sum=k-dp[2][i];               if(sum<=0)                   ans=min(ans,dp[2][i]);               else                   ans=min(ans,dp[2][i]+(sum/all)*all+(sum%all>0)*all);          }          printf("%lld\n",ans);    }    return 0;}
原创粉丝点击