zoukankan      html  css  js  c++  java
  • USACO 2017 February Contest Gold T1: Why Did the Cow Cross the Road

    题目大意

    奶牛们为什么要穿马路?一个原因只是因为FJ的牧场的路实在是太多了,使得奶牛们每天不得不穿梭在许许多多的马路中央。

    FJ的牧场可以看作是一块N×N 的田地(3N100),N1 条南北向的道路和 N1 条东西向的道路贯穿整个牧场,同时是每块田野的分界线。牧场的最外面是一圈高大的栅栏以防止奶牛离开牧场。

    Bessie只要穿过分离两块田野的道路,就可以从任何田野移动到与其相邻的田野里去(北,东,南或西)。当然,Bessie穿过每一条马路都是需要 T 时间的。(0T1,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 }
  • 相关阅读:
    javascript中依赖属性(Dependency Property)的实现
    金山卫士UI原理解析(2)CBkWindow
    WTL学习笔记(5)双缓冲技术和动画(BufferedPaint)
    数据结构队列
    Windows下如何自定义窗体控件
    金山卫士UI原理解析(1)
    WTL学习笔记(4)控件加强
    WTL学习笔记(5)系统皮肤管理
    小笨开始冬眠了:)
    送时尚数码展门票
  • 原文地址:https://www.cnblogs.com/LI-dox/p/11228496.html
Copyright © 2011-2022 走看看