zoukankan      html  css  js  c++  java
  • bzoj2143: 飞飞侠

    表示自己dij写挫了QWQ

    直接建边肯定是很不可做的,那么考虑转换一下,假如我在这里选择跳,相当于可以走a[i][j]步

    三次dij

    这样转移是150^3次方,强行算完是会T的,那么其实找到了那两个位置就够了

    #include<cstdio>
    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    #include<queue>
    using namespace std;
    typedef long long LL;
    const int dx[5]={-1,0,1,0,0};
    const int dy[5]={0,1,0,-1,0};
    int read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
        return x*f;
    }
    
    int n,m;
    int b[210][210],X[3],Y[3];
    LL a[210][210],cost[3];
    
    struct dij
    {
        int x,y,z;LL k;
        dij(){}
        dij(int X,int Y,int Z,LL K){x=X,y=Y,z=Z,k=K;}
        friend bool operator>(dij d1,dij d2){return d1.k>d2.k;}
        friend bool operator<(dij d1,dij d2){return d1.k<d2.k;}
    };priority_queue<dij,vector<dij>,greater<dij> >q;
    LL d[210][210][310];
    bool v[210][210][310];
    void dijkstra(int w)
    {
        memset(d,63,sizeof(d));d[X[w]][Y[w]][0]=0;
        memset(v,false,sizeof(v));
        q.push(dij(X[w],Y[w],0,d[X[w]][Y[w]][0]));
        while(!q.empty()&&(!v[X[0]][Y[0]][0]||!v[X[1]][Y[1]][0]||!v[X[2]][Y[2]][0]))
        {
            dij tno=q.top();q.pop();
            int x=tno.x,y=tno.y,z=tno.z;
            if(v[x][y][z]==true)continue;
            v[x][y][z]=true;
            
            if(z>0)
            {
                for(int k=0;k<=4;k++)
                {
                    int tx=x+dx[k],ty=y+dy[k];
                    if(0<tx&&tx<=n&&0<ty&&ty<=m)
                    {
                        if(d[tx][ty][z-1]>d[x][y][z])
                        {
                            d[tx][ty][z-1]=d[x][y][z];
                            q.push(dij(tx,ty,z-1,d[tx][ty][z-1]));
                        }
                    }
                }
            }
            else
            {
                if(d[x][y][b[x][y]]>d[x][y][z]+a[x][y])
                {
                    d[x][y][b[x][y]]=d[x][y][z]+a[x][y];
                    q.push(dij(x,y,b[x][y],d[x][y][b[x][y]]));
                }
            }
        }
        while(!q.empty())q.pop();
        
        for(int i=0;i<=2;i++)
        {
            if(d[X[i]][Y[i]][0]==d[0][0][0])cost[i]=-1;
            if(cost[i]!=-1)cost[i]+=d[X[i]][Y[i]][0];
        }
    }
    int main()
    {
        freopen("a.in","r",stdin);
        freopen("a.out","w",stdout);
        n=read(),m=read();
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                b[i][j]=read(),b[i][j]=min(b[i][j],300);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                a[i][j]=read();
        
        for(int i=0;i<=2;i++)
            X[i]=read(),Y[i]=read();
        
        memset(cost,0,sizeof(cost));    
        for(int i=0;i<=2;i++)dijkstra(i);
        
        if(cost[0]==-1&&cost[1]==-1&&cost[2]==-1)printf("NO
    ");
        else
        {
            for(int i=0;i<=2;i++)
                if(cost[i]==-1)cost[i]=(1LL<<62);
                 if(cost[0]<=cost[1]&&cost[0]<=cost[2])printf("X
    %lld
    ",cost[0]);
            else if(cost[1]<=cost[0]&&cost[1]<=cost[2])printf("Y
    %lld
    ",cost[1]);
            else if(cost[2]<=cost[0]&&cost[2]<=cost[1])printf("Z
    %lld
    ",cost[2]);
        }
        return 0;
    }
  • 相关阅读:
    bzoj 1022: [SHOI2008]小约翰的游戏John anti_nim游戏
    spoj gss2 : Can you answer these queries II 离线&&线段树
    hduoj 1077 Catching Fish 求单位圆最多覆盖点个数
    HDUOJ Clear All of Them I 状压DP
    bzoj 1013: [JSOI2008]球形空间产生器sphere 高斯消元
    bzoj 1006: [HNOI2008]神奇的国度 弦图的染色问题&&弦图的完美消除序列
    Cocos2d-x Lua中生命周期函数
    Cocos2d-x Lua中使用标签
    Cocos2d-x Lua中Sprite精灵类
    Cocos2d-x Lua Node与Node层级架构
  • 原文地址:https://www.cnblogs.com/AKCqhzdy/p/9581205.html
Copyright © 2011-2022 走看看