hiho185

题目1 : 积水的城市
时间限制:10000ms
单点时限:1000ms
内存限制:256MB
描述
如下图所示,某市市区由M条南北向的大街和N条东西向的道路组成。其中由北向南第i条路和第i+1条路之间的距离是Bi (1 <= i < N),由西向东第i条街和第i+1条街之间的距离是Ai (1 <= i < M)。

这里写图片描述

小Ho现在位于第x条路和第y条街的交叉口,他的目的地是第p条路和第q条街的交叉口。由于连日降雨,城市中有K个交叉口积水太深不能通行。小Ho想知道到达目的地的最短路径的长度是多少。

输入
第一行包含两个整数N和M。(1 <= N, M <= 500)

第二行包含N-1个整数, B1, B2, B3, … BN-1。(1 <= Bi <= 100)

第三行包含M-1个整数, A1, A2, A3, … AM-1。(1 <= Ai <= 100)

第四行包含一个整数K,表示积水的交叉口的数目。 (0 <= K <= 30)

以下K行每行包含2个整数,X和Y,表示第X条路和第Y条街的交叉口积水。(1 <= X <= N, 1 <= Y <= M)

第K+5行包含一个整数Q,表示询问的数目。 (1 <= Q <= 10)

以下Q行每行包含4个整数x, y, p, q,表示小Ho的起止点。起止点保证不在积水的交叉口处。 (1 <= x, p <= N, 1 <= y, q <= M)

输出
对于每组询问,输出最短路的长度。如果小Ho不能到达目的地,输出-1。

样例输入
4 5
2 4 1
3 3 3 2
3
1 3
2 3
3 2
1
1 2 2 4
样例输出
24

思路:直接把交叉点的二维坐标映射成一维的点,因为矩阵边长最大值是500所以最多一共有250000个顶点,大约4*250000=1000000条边,这是很稀疏的图,而且邻接矩阵也存不下,于是用邻接表,求最短路套spfa的模板,建图的比较恶心。
#include <iostream>
#include <queue>
#include <cstring>

using namespace std;

const int M = 10000005;
const int INF = 999999999;
struct node
{
    int u;
    int v;
    int c;

}p[M];

int Next[M];
int  head[M];
long long dist[M];
bool visit[M];
int  now[M];

int  e,top;
int  a,b;
int n,m,k,x,y,Q,p0,q0;

void addnode(int  a,int  b,int c)
{
    p[e].c = c;
    p[e].u = a;
    p[e].v = b;
    Next[e] = head[a];
    head[a] = e++;

}

void init()
{
    memset(head,-1,sizeof(head));
    memset(Next,-1,sizeof(Next));
    e = 0;

}

bool relax(int  u,int  v,int c)
{
    if(dist[v]> dist[u]+c){
        dist[v] = dist[u] + c;
        return true;
    }
    return false;
}

void spfa(int  t)
{   int  j,i;
    int num = n*m;
    memset(visit,0,sizeof(visit));
    for(i=0;i<num;i++){
        dist[i] = INF;
    }
    dist[t] = 0;
    visit[t] = true;
    queue <int>Q;
    Q.push(t);
    while(!Q.empty()){
        int pre = Q.front();
        Q.pop();
        visit[pre] = false;
        for(int i = head[pre];i+1;i=Next[i] ){
            if(relax(pre,p[i].v,p[i].c)&&!visit[p[i].v]){
                Q.push(p[i].v);
                visit[p[i].v] = true;
            }
        }
    }
}
int G[505][505];

int dir[4][2] = {{0,1},{-1,0},{1,0},{0,-1}};

int main()
{

    int A[505];
    int B[505];
    cin>>n>>m;

    int num = n*m;

    for(int i = 1; i < n; ++i)
        cin>>B[i];

    for (int i = 1; i < m; ++i)
        cin>>A[i];

    for (int i = 0; i < n ; ++i)
        for (int j = 0; j < m ; ++j)
            G[i][j] = 0;
    init();

    cin>>k;
    for (int i = 0; i < k; ++i){
        cin>>x>>y;
        G[x-1][y-1] = -1;
    }
    for (int i = 0; i < n; ++i){
        for (int j = 0; j < m; ++j){
            if(G[i][j]!= -1 ){
            if( i < n-1 && j < m-1 ){
                if(G[i][j+1]!=-1){
                addnode(i*m+j,i*m+j+1,A[j+1]);
                addnode(i*m+j+1,i*m+j,A[j+1]);
                }
                if(G[i+1][j]!=-1){
                addnode(i*m+j,(i+1)*m+j,B[i+1]);
                addnode((i+1)*m+j,i*m+j,B[i+1]);
                }
            }
            if(j == m-1 && i <= n-2){
                addnode(i*m+j,(i+1)*m+j,B[i+1]);
                addnode((i+1)*m+j,i*m+j,B[i+1]);
            }
            if(i == n-1 && j <= m-2){
                addnode(i*m+j,i*m+j+1,A[j+1]);
                addnode(i*m+j+1,i*m+j,A[j+1]);
            }
            }
            else{
                for(int k = 0; k < 4; ++k){
                    int dx = i + dir[k][0];
                    int dy = j + dir[k][1];
                    if(dx >=0 && dx < n && dy >=0 && dy < m){
                        addnode(i*m+j,dx*m+dy,INF);
                        addnode(dx*m+dy,i*m+j,INF);

                    }
                }
            }
        }
    }

    cin>>Q;
    while(Q--){
    cin>>x>>y>>p0>>q0;
    int u = (x-1)*m + y-1;
    int v  = (p0-1)*m + q0-1;
    spfa(u);
    if(dist[v]<INF)
        cout<<dist[v]<<endl;
    else
        cout <<"-1"<<endl;

    }
    return 0;
}
上面的代码不知道什么原因一直只有90分,后来看了一下别人的用优先队列优化的BFS觉得代码比较简单,于是学习一波
#include <iostream>
#include <queue>
#include <cstring>
#include <algorithm>

using namespace std;

const int M = 550+5;
const int INF =  100000;

int n,m,k,q;
int a[M],b[M],G[M][M],vis[M][M];
int dir[4][2] = {{-1,0},{1,0},{0,-1},{0,1}};



int dis(int x,int y,int i)
{
    if( i == 0) return a[x-1];
    if( i == 1) return a[x];
    if( i == 2) return b[y-1];
    return b[y];
}

typedef struct node
{
    int x,y,d;
    node(){}
    node(int u,int v,int c) : x(u),y(v),d(c){}
    node go(int i){
       return node(x+dir[i][0],y+dir[i][1],d+dis(x,y,i));
    }

    bool operator < (const node &s) const{
        return d > s.d;
    }

    bool isok(){

        return x>=1&&x<=n&&y>=1&&y<=m&&!vis[x][y];
    }
};

int main()
{

    cin>>n>>m;

    for(int i = 1; i < n; ++i)
        cin>>a[i];
    for(int i = 1; i < m; ++i)
        cin>>b[i];

    cin>>k;
    for(int i = 1; i <= k; ++i){
        int x,y;
        cin>>x>>y;
        vis[x][y] = 1;
    }
    cin>>q;
    while(q--){
        fill(G[0], G[550] + 550, INF);
        int x, y, s, t;
        cin >> x >> y >> s >> t;
        G[x][y] = 0;
        node start(x,y,0);
        priority_queue<node>que;
        que.push(start);
        while(!que.empty()){
            node now = que.top();
            que.pop();
            for (int i = 0; i < 4; ++i){
                node tmp = now.go(i);
                if(tmp.isok()){
                    if(G[tmp.x][tmp.y] > G[now.x][now.y] + dis(now.x,now.y,i)){
                        G[tmp.x][tmp.y] = G[now.x][now.y] + dis(now.x,now.y,i);
                        que.push(tmp);
                    }
                }
            }
        }
        if(G[s][t]!=INF) cout <<G[s][t]<<endl;
        else
            cout<<"-1"<<endl;
    }

    return 0;
}





weixin073智慧旅游平台开发微信小程序+ssm后端毕业源码案例设计 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
python017基于Python贫困生资助管理系统带vue前后端分离毕业源码案例设计 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值