zoukankan      html  css  js  c++  java
  • codevs 2074 营救 WW

                         题目描述 Description

           在一个n*m的一个方块阵阵地上仅由楼房和街道组成,现在你在(x1,y1)点,伤员在(x2,y2)点,你可以向周围的8个方向移动,也可以爬上一部分楼房。而伤员因为受了伤,动弹不得,你必须背他回来。因此你所最担心的不是你的路程长短,而是你在救援中费的力气的大小。你爬上一幢高为H的楼房,或者从高为H的楼房房顶下来,都需要花费H的力气,而没有高度落差的行走是不费力的。现在你要完成救援的任务,最少要花费多少力气呢?费力最小的情况下,你最少又要走多少路呢?这里上、下楼不算走路。

    输入描述 Input Description

           输入文件的第1行有两个正整数n,m(n,m<=500),第2,3行分别是(x1,y1),(x2,y2)(1<=x1,x2<=n,1<=y1,y2<=m)。接下来有n行,每行m个数,第I行,第J列为1表示此处为空地,为2表示此处为房顶,为0表示此处无法攀爬。保证起点,终点不在0上,你可以假设可攀爬的楼房高度都为1。你到了(x2,y2)就表示救援成功。

    输出描述 Output Description

           输出文件包括两个在一行的数x,y,用一个空格隔开。X表示费力最少的情况下,路径的最短长度,Y表示最少花费的力气量。若无法完成营救任务,则输出’0 0’(引号不输出)。

    样例输入 Sample Input
    3 7
    1 1
    3 7
    2100212
    2121010
    2221012
    样例输出 Sample Output

    8 4

    数据范围及提示 Data Size & Hint

    30%的数据满足:n,m<=10

    100%的数据满足:n,m<=500

    数据有问题:

    10 10

    1 1

    10 10

    1 0 1 2 0 1 0 1 0 0

    1 1 1 1 1 0 2 2 2 2

    1 2 1 2 0 1 2 1 2 1

    1 1 2 2 2 0 2 2 1 2  

    1 1 2 2 2 1 0 2 1

    1 0 0 2 0 2 0 1 1

    2 0 1 0 2 1 2 1 0 0

    0 1 0 1 1 2 1 1 2 1

    0 0 2 0 0 1 2 0 0 0

    2 0 1 0 2 1 1 1 1 1

    应该为13,answer为14

    ???

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<queue>
    #include<cstring>
    
    using namespace std;
    const int N=2500001;
    const int Maxn=99999999;
    const int xd[]={0,-1,-1,-1,0,1,1,1};
    const int yd[]={-1,-1,0,1,1,1,0,-1};
    
    int head[N*2];
    int now=1;
    int a[251*2][251*2];
    bool visit[N];
    int dis[N];
    int pre[N];
    int strx,stry,endx,endy;
    int n,m;
    queue<int>q;
    
    struct node{
        int u,v,w,nxt;
    }E[N*2];
    
    inline int read()
    {
        int x=0;
        char c=getchar();
        while(c<'0'||c>'9')c=getchar();
        while(c>='0'&&c<='9')
        return x=c-'0';
    }
    
    inline void add(int u,int v,int w)
    {
        E[now].v=v;
        E[now].w=w;
        E[now].nxt=head[u];
        head[u]=now++;
    }
    
    inline void to_build_picture()
    {
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                for(int k=0;k<8;k++)
                {
                    int x=i+xd[k];
                    int y=j+yd[k];
                    if(a[x][y])
                    {
                        if(a[x][y]==1)
                            add((i-1)*m+j,(x-1)*m+y,0);
                        else
                            add((i-1)*m+j,(x-1)*m+y,2);
                    }
                }
        now--;
    }
    
    inline void spfa_to_ac(int start,int endd)
    {
        for(int i=1;i<=now;i++)
            dis[i]=Maxn;
        dis[start]=0;
        visit[start]=1;
        q.push(start);
        while(!q.empty())
        {
            int top=q.front();
            q.pop();
            visit[top]=0;
            for(int i=head[top];i!=-1;i=E[i].nxt)
                if(dis[E[i].v]>dis[top]+E[i].w)
                {
                    dis[E[i].v]=dis[top]+E[i].w;
                    pre[E[i].v]=top;
                    if(!visit[E[i].v])
                        q.push(E[i].v);
                }        
        }
    }
    
    int main()
    {
        scanf("%d%d%d%d%d%d",&n,&m,&strx,&stry,&endx,&endy);
        memset(head,-1,sizeof(head));
        
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                a[i][j]=read();
                
        to_build_picture();
            
        int start=(strx-1)*m+stry;
        int endd=(endx-1)*m+endy;
        spfa_to_ac(start,endd); 
        
        int answer;
        if(a[strx][stry]==1)
            answer=dis[endd];
        else answer=dis[endd]-1;
        if(answer==Maxn)
        {
            printf("0 0");
            return 0;
        }
        int ans(1);
        while(pre[endd]!=start)
        {
            //cout<<endd<<" "<<endl;
            ans++;
            endd=pre[endd];
        }
        printf("%d %d",ans,answer);
        return 0;
    }
    /*
    3 7
    1 1
    3 7
    2 1 0 0 2 1 2
    2 1 2 1 0 1 0
    2 2 2 1 0 1 2
    
    */

     正解:

    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    using namespace std;
    
    struct data {    int d,t;
    };
    data f[3000000];
    struct node {
        int x,y,d,t,next;
    };
    node q[1000010];
    int last[300000],len=0,idp=0;
    int n,m,x1,y1,x2,y2;
    int p[1000010],st=1,ed=2;
    bool v[1000010];
    char map[510][510];
    int id[510][510];
    
    void ins(int x,int y,int t,int d)
    {
        len++;
        q[len].x=x;
        q[len].y=y;
        q[len].t=t;
        q[len].d=d;
        q[len].next=last[x];
        last[x]=len;
    }
    void build()
    {
        int fx[8]= {1,-1,0,0,-1,-1,1,1};
        int fy[8]= {0,0,-1,1,-1,1,-1,1};
        for(int i=0; i<n; i++)
        {
            for(int j=0; j<m; j++)
            {
                if(map[i][j]=='0') continue;
                if(id[i][j]==-1) id[i][j]=++idp;
                for(int k=0; k<8; k++)
                {
                    int tx=i+fx[k];
                    int ty=j+fy[k];
                    if(tx>=0 && tx<n && ty>=0 && ty<m && map[tx][ty]!='0')
                    {
                        if(id[tx][ty]==-1) id[tx][ty]=++idp;
                        ins(id[i][j],id[tx][ty],(map[i][j]!=map[tx][ty]),1);
                    }
                }
            }
        }
    }
    
    int main()
    {
        memset(f,63,sizeof(f));
        memset(last,-1,sizeof(last));
        memset(v,false,sizeof(v));
        memset(id,-1,sizeof(id));
        scanf("%d %d",&n,&m);
        scanf("%d %d",&x1,&y1);
        x1--;
        y1--;
        scanf("%d %d",&x2,&y2);
        x2--;
        y2--;
        for(int i=0; i<n; i++)
        {
            scanf("%s",map[i]);
        }
        build();
        f[id[x1][y1]].t=0;
        f[id[x1][y1]].d=1;
        p[1]=id[x1][y1];
        v[id[x1][y1]]=true;
        while(st!=ed)
        {
            int x=p[st];
            for(int i=last[x]; i!=-1; i=q[i].next)
            {
                int y=q[i].y;
                if(f[y].t>f[x].t+q[i].t)
                {
                    f[y].t=f[x].t+q[i].t;
                    f[y].d=f[x].d+q[i].d;
                    if(v[y]==false)
                    {
                        v[y]=true;
                        p[ed++]=y;
                        if(ed>idp) ed=1;
                    }
                }
                else if(f[y].t<f[x].t+q[i].t) continue;
                else if(f[y].d>f[x].d+q[i].d)
                {
                    f[y].d=f[x].d+q[i].d;
                    if(v[y]==false)
                    {
                        v[y]=true;
                        p[ed++]=y;
                        if(ed>idp) ed=1;
                    }
                }
            }
            v[x]=false;
            st++;
            if(st>idp) st=1;
        }
        if(f[id[x2][y2]].t==1061109567 && f[id[x2][y2]].d==1061109567) printf("0 0");
        else printf("%d %d",f[id[x2][y2]].d,f[id[x2][y2]].t);
    }
  • 相关阅读:
    第三天 moyax
    mkfs.ext3 option
    write file to stroage trigger kernel warning
    download fomat install rootfs script
    custom usb-seriel udev relus for compatible usb-seriel devices using kermit
    Wifi Troughput Test using iperf
    learning uboot switch to standby system using button
    learning uboot support web http function in qca4531 cpu
    learngin uboot design parameter recovery mechanism
    learning uboot auto switch to stanbdy system in qca4531 cpu
  • 原文地址:https://www.cnblogs.com/lyqlyq/p/7067306.html
Copyright © 2011-2022 走看看