您的位置:首页 > 其它

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

2017-09-02 09:35 302 查看
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 long
using 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: