您的位置:首页 > 编程语言 > Go语言

Problem A. Travel Google APAC 2016 University Test Round B

2017-02-25 10:56 465 查看
这一题是最短路,但是因为cost随时间变化,需要考虑最优性原理是否满足。因为Dijkstra算法本质上是DP。

因为cost[t]<=cost[t+1]+1,考虑a to b to c这样一条路径。如果a到b有两条path1和path2,p1<p2,那么有没有可能p1+cost from b to c>p2+cost from b to c呢?

Since p1+1<=p2, departing time t1 at c (along path1) < departing time t1 at c (along path2), then cost[t1]<=cost[t2]+c, c>=1. Adding two inequalities, we have p1+cost[t1]<=p2+cost[t2]+c-1, walking
along path1 is still no worse than path2.

考虑隔夜的case,cost[t1]<=cost[23]+c<=cost[0]+c+1<=cost[t2]+c+c2. 其中t1是第一天,t2是第二天,cost不等式关系仍然成立,所以隔夜的case也满足最优性原理。

看了大神的博客,更好的做法是预处理从0~23 o'clock出发的最短距离,再O(1)查询。即,用dis[i][S]记录出发时间为S,从1到i的最短路。

开始WA是因为没注意边是bidiectional的。

#include<iostream>
#include<stdio.h>
#include<cstdio>
#include<string>
#include<cmath>
#include<stdlib.h>
#include<algorithm>
#include<string.h>
#include<cstring>
#include<vector>
#include<queue>
#include<map>
#include<set>

using namespace std;

//2016 Round B Problem A. Travel
int T;
const int maxn=510;
int N;
int M;
int K;
int mp[maxn][maxn];
int cost[maxn][maxn][24];
int D;
int S;
int dis[maxn];//arriving time=S+distance
const int INF=0x3f3f3f3f;
bool vis[maxn];
class ComparisonClass
{
public:
bool operator()(pair<int,int>a,pair<int,int>b)
{
if(a.first==b.first)
{
return a.second>b.second;//second is index
}
return a.first>b.first;//first is distance
}
};
int shortest()
{
memset(dis,0x3f,sizeof(dis));
memset(vis,false,sizeof(vis));
dis[1]=0;
priority_queue<pair<int,int>,vector<pair<int,int> >,ComparisonClass> que;
que.push(make_pair(0,1));
while(!que.empty())
{
pair<int,int>now=que.top();
vis[now.second]=true;
que.pop();
if(now.second==D)
{
return dis[D];
}
//        cout<<now.second<<" "<<now.first<<endl;
for(int i=1;i<=N;i++)
{
//cout<<mp[now.second][i]<<endl;
if(mp[now.second][i]==0) continue;
if(vis[i]==true) continue;
//cout<<" "<<dis[now.second]+S<<cost[now.second][i][dis[now.second]+S]<<endl;
if(dis[i]>now.first+cost[now.second][i][(dis[now.second]+S)%24])
{
dis[i]=now.first+cost[now.second][i][(dis[now.second]+S)%24];
que.push(make_pair(dis[i],i));
//cout<<"upd "<<i<<" "<<dis[i]<<endl;
}
}
}
return dis[D];
}
int main()
{
freopen("A-large-practice.in","r",stdin);
//    freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
scanf("%d",&T);
for(int ca=1;ca<=T;ca++)
{
printf("Case #%d: ",ca);
memset(mp,0,sizeof(mp));
memset(cost,0,sizeof(cost));
scanf("%d %d %d",&N,&M,&K);
for(int i=0;i<M;i++)
{
int x=0;
int y=0;
scanf("%d %d",&x,&y);
mp[x][y]=1;
mp[y][x]=1;
for(int j=0;j<24;j++)
{
scanf("%d",&cost[x][y][j]);
cost[y][x][j]=cost[x][y][j];
}
}
for(int i=0;i<K;i++)
{
scanf("%d %d",&D,&S);
int ans=shortest();
if(ans==INF)
{
printf("-1");
}
else
{
printf("%d",ans);
}
if(i==K-1)
{
printf("\n");
}
else
{
printf(" ");
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: