题目大意
奶牛们为什么要穿马路?一个原因只是因为FJ的牧场的路实在是太多了,使得奶牛们每天不得不穿梭在许许多多的马路中央。
FJ的牧场可以看作是一块N×N 的田地(3≤N≤100),N−1 条南北向的道路和 N−1 条东西向的道路贯穿整个牧场,同时是每块田野的分界线。牧场的最外面是一圈高大的栅栏以防止奶牛离开牧场。
Bessie只要穿过分离两块田野的道路,就可以从任何田野移动到与其相邻的田野里去(北,东,南或西)。当然,Bessie穿过每一条马路都是需要 T 时间的。(0≤T≤1,000,000)
有一天,FJ邀请Bessie来他家下棋,Bessie从牧场的西北角出发,FJ的家在牧场的东南角。因为Bessie在中途可能会饿,所以她每走过三块田野就要停下来,享用她所在田野上的新鲜的牧草(不包括Bessie的出发点,但是可能会包括终点FJ的家),
牧场上有些田野的牧草长得比其他地方茂盛,所以Bessie对应的停留时间也会变长。
请帮帮Bessie计算出她走到FJ家的最短时间。
题目分析
观察数据范围,N最大只有100,所以最多有1e4个点。
因为要求最短时间,而点数太多,所以不考虑搜索,考虑使用最短路。
然而每走三块田地要停下来,所以,我们把一个点与从它走三步所能到达的点连边。然后跑个最短路就行。
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int MAXN=2e4+10; 5 const ll Inf=1e18+7; 6 struct Edge{ 7 int to,nxt; 8 ll dis; 9 }e[MAXN<<4]; 10 int cnt,head[MAXN]; 11 inline void add_edge(int u,int v,ll d){ 12 e[++cnt].to=v;e[cnt].nxt=head[u];e[cnt].dis=d;head[u]=cnt; 13 } 14 15 struct Node{ 16 ll dis; 17 int pos; 18 inline bool operator<(const Node &x)const{ 19 return x.dis<dis; 20 } 21 }; 22 23 int n; 24 ll t,g[105][105]; 25 int dx[20]={-1,-2,-3,-1,-2,0,1,2,1,2,3,0,0,1,0,-1}; 26 int dy[20]={-2,-1,0,2,1,-3,-2,-1,2,1,0,3,1,0,-1,0}; 27 ll dis[MAXN],ans; 28 bool vis[MAXN]; 29 inline int Id(int x,int y){return (x-1)*n+y;} 30 priority_queue<Node> q; 31 inline void Dijkstra(){ 32 for(int i=1;i<=n*n;++i) 33 dis[i]=Inf; 34 //puts(""); 35 //for(int i=1;i<=n;++i){ 36 // for(int j=1;j<=n;++j) 37 // printf("%lld ",dis[Id(i,j)]); 38 // printf(" "); 39 //} 40 q.push((Node){(ll)0,Id(1,1)}); 41 dis[Id(1,1)]=0; 42 while(!q.empty()){ 43 Node fa=q.top(); 44 int x=fa.pos; 45 q.pop(); 46 if(vis[x]) continue; 47 vis[x]=1; 48 for(int i=head[x],y;i;i=e[i].nxt){ 49 y=e[i].to; 50 if(dis[y]>dis[x]+e[i].dis){ 51 dis[y]=dis[x]+e[i].dis; 52 q.push((Node){dis[y],y}); 53 } 54 } 55 } 56 } 57 int main(){ 58 scanf("%d%lld",&n,&t); 59 for(int i=1;i<=n;++i) 60 for(int j=1;j<=n;++j) 61 scanf("%lld",&g[i][j]); 62 for(int i=1;i<=n;++i) 63 for(int j=1;j<=n;++j){ 64 for(int k=0;k<16;++k){ 65 if(i+dx[k]>=1&&i+dx[k]<=n&&j+dy[k]>=1&&j+dy[k]<=n){ 66 add_edge(Id(i,j),Id(i+dx[k],j+dy[k]),3*t+g[i+dx[k]][j+dy[k]]); 67 //cout<<3*t+g[i+dx[k]][j+dy[k]]<<' '<<i+dx[k]<<' '<<j+dy[k]<<endl; 68 } 69 } 70 } 71 Dijkstra(); 72 ans=Inf; 73 for(int i=1;i<=n;++i) 74 for(int j=1;j<=n;++j) 75 if(2*n-i-j<3) 76 ans=min(ans,dis[Id(i,j)]+(ll)t*(2*n-i-j)); 77 // for(int i=1;i<=n;++i){ 78 // for(int j=1;j<=n;++j) 79 // printf("%lld ",dis[Id(i,j)]); 80 // printf(" "); 81 // } 82 printf("%lld ",ans); 83 return 0; 84 }