• luogu4473 BZOJ2143 2011[国家集训队]飞飞侠


    题目戳这里

    有问题可以在博客@

    应该还会有人来看吧,嘻嘻


    正题:

    题目大意:

    题目很清楚,就是一个点有一定的范围,会有一定的花费
    求三个点中的任意两个点到另一个点的最小花费
    (麻麻教育我千万读好题目(>_<)~)

    思路

    很容易想到跑最短路,但是建边的话,根本存不下来

    所以我们直接存点的坐标,然后直接遍历范围内每个点就好了(遍历是看图找规律吧,反正我动脑子看不出来)

    跑一边最短路就好了

    bzoj完全没问题,这里指luogu

    spfa?他好像又死了(o2水过)

    堆优化迪杰斯特拉是个好东西

    我是先写的spfa,然后改了改一丢丢就写成了迪杰斯特拉,感觉他俩好像啊

    下面是dijkstar和死了的spfa

    代码:堆优化迪杰斯特拉

    #include <cstdio>
    #include <cmath>
    #include <algorithm>
    #include <cstring>
    #include <queue>
    #include <iostream>
    #define maxn 155
    #define inf 0x3f3f3f3f
    using namespace std;
    int n,m;
    int a[maxn][maxn];
    int b[maxn][maxn];
    int dis[maxn][maxn];
    int x[4],y[4];
    int PKU[4][4];
    struct node 
    {
        int x,y,q;
        node(int xx,int yy,int qq)
        {
            x=xx;y=yy;
    		q=qq;
        }
        bool operator < (const node &a) const 
        {
        	return q>a.q;
    	}
    };
    inline int read()
    {
        int x=0,f=1;char s=getchar();
        while('0'>s||s>'9') {if(s=='-')f=-1;s=getchar();}
        while('0'<=s&&s<='9') {x=(x<<3)+(x<<1)+s-'0';s=getchar();}
        return x*f;
    }
    void dijstra(int js)
    {
        memset(dis,inf,sizeof(dis));
        priority_queue<node> q;
        q.push(node(x[js],y[js],0));
        dis[x[js]][y[js]]=0;
        while(!q.empty())
        {
            node u=q.top();
            q.pop();
            if(dis[u.x][u.y]!=u.q) continue;
            int len=b[u.x][u.y];
            int v=dis[u.x][u.y]+a[u.x][u.y];
            for(int i=max(1,u.x-len);i<=min(n,u.x+len);++i)
            {
                int tmp=len-abs(u.x-i);
                for(int j=max(1,u.y-tmp);j<=min(m,u.y+tmp);j++)
                {
                    if(dis[i][j] > v)
                    {
                        dis[i][j] = v;
                        q.push(node(i,j,dis[i][j]));
                    }
                }
            }
        }
        for(int i=1;i<=3;++i) PKU[js][i]=dis[x[i]][y[i]];
    }
    int main(int argc, char const *argv[])
    {
        n=read();m=read();
        for (int i = 1; i <= n; ++i)
            for (int j = 1; j <= m; ++j)
                b[i][j]=read();
        for (int i = 1; i <= n; ++i)
            for (int j = 1; j <= m; ++j)
                a[i][j]=read();
        for (int i = 1; i <= 3; ++i)
        {
            x[i]=read();
            y[i]=read();
        }
        for(int i=1;i<=3;++i) dijstra(i);
        int id=0,ans=inf;
        for(int i=1;i<=3;++i)
    	{
            int tm=PKU[1][i]+PKU[2][i]+PKU[3][i];
            if(ans>tm) ans=tm,id=i;
        }
        if(ans==inf) return puts("NO"),0;
        if(id==1) puts("X");
        if(id==2) puts("Y");    
        if(id==3) puts("Z");
        printf("%d",ans);
        return 0;
    }
    

    代码:spfa

    	#include <cstdio>
    #include <cmath>
    #include <algorithm>
    #include <cstring>
    #include <queue>
    #include <iostream>
    #define maxn 155
    #define inf 0x3f3f3f3f
    using namespace std;
    int n,m;
    int a[maxn][maxn];
    int b[maxn][maxn];
    int dis[maxn][maxn];
    int vis[maxn][maxn];
    int x[4],y[4];
    int PKU[4][4];
    struct node 
    {
        int x,y;
        node(int xx,int yy)
        {
            x=xx;y=yy;
        }
    };
    inline int read()
    {
        int x=0,f=1;char s=getchar();
        while('0'>s||s>'9') {if(s=='-')f=-1;s=getchar();}
        while('0'<=s&&s<='9') {x=(x<<3)+(x<<1)+s-'0';s=getchar();}
        return x*f;
    }
    void spfa(int js)
    {
        memset(dis,inf,sizeof(dis));
        queue<node> q;
        q.push(node(x[js],y[js]));
        dis[x[js]][y[js]]=0;
        while(!q.empty())
        {
            node u=q.front();
            q.pop();vis[u.x][u.y]=0;
            int len=b[u.x][u.y];
            int v=dis[u.x][u.y]+a[u.x][u.y];
            for(int i=max(1,u.x-len);i<=min(n,u.x+len);++i)
            {
                int tmp=len-abs(u.x-i);
                for(int j=max(1,u.y-tmp);j<=min(m,u.y+tmp);j++)
                {
                    if(dis[i][j] > v)
                    {
                        dis[i][j] = v;
                        if(!vis[i][j])
                        {
                            vis[i][j]=1;
                            q.push(node(i,j));
                        }
                    }
                }
            }
        }
        for(int i=1;i<=3;++i) PKU[js][i]=dis[x[i]][y[i]];
    }
    int main(int argc, char const *argv[])
    {
        n=read();m=read();
        for (int i = 1; i <= n; ++i)
            for (int j = 1; j <= m; ++j)
                b[i][j]=read();
        for (int i = 1; i <= n; ++i)
            for (int j = 1; j <= m; ++j)
                a[i][j]=read();
        for (int i = 1; i <= 3; ++i)
        {
            x[i]=read();
            y[i]=read();
        }
        for(int i=1;i<=3;++i) spfa(i);
        int id=0,ans=inf;
        for(int i=1;i<=3;++i)
        {
            int tm=PKU[1][i]+PKU[2][i]+PKU[3][i];
            if(ans>tm)
            {
                ans=tm;
                id=i;
            }
        }
        if(ans==inf)
            return puts("NO"),0;
        if(id==1)
            puts("X");
        if(id==2)
        	puts("Y");    
        if(id==3)
            puts("Z");
        printf("%d",ans);
        return 0;
    }
    

    厚颜无耻的骗波赞( • ̀ω•́ )✧

  • 相关阅读:
    格式化代码
    hexdump命令
    shell中+,*,[:space:]的用法
    Linux下安装Android的adb驱动-解决不能识别的问题
    android launcher3 home页简易分析
    LINUX 内核代码 errno 错误代码提示 /include/asm/errno.h
    关于mtk Android打开串口权限问题
    关于android MTK相机L版本,切换屏幕比例后,分辨率随之改变,但重新进入相机后原有分辨率不再生效问题
    关于android应用闪屏的几种情况
    Android 笔记
  • 原文地址:https://www.cnblogs.com/dsrdsr/p/9525890.html
Copyright © 2020-2023  润新知