【2018.3.10】模拟赛之四-ssl2133 腾讯大战360【SPAF,图论,最短路径】

本文介绍了一种使用双遍SPFA算法求解特定场景下两点间最短相遇路径的问题,通过建立邻接表并利用哈希方法优化存储结构,最终通过枚举相遇点来确定最小时间消耗。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录地址

前言

打错了一个地方之接60,还有输出“Peace”能拿60。还有题目坑爹害得我用了哈希,可以无视 QAQ


正题

有一个n*n的图,有m条边,不知道几个城市,给出两个位置,求两个位置移动到相遇(不能再路上)的最短路径。


输入输出(需要自取)

Input

输入数据第一行:N和M(用空格隔开) 表示这是一个N*N的图并且有M条边,第二行到第M+1行 为这个图的详细信息。
每行共有被空格隔开的三个数:a b c。表示编号为a的城市到编号为b的城市
有一个双向边,并且要过这条双向边所需要花费的时间为c。
最后一行有两个数:S和T,S表示腾讯所处的城市(也就是深圳),T表示360所处的
城市(也就是北京)

Output

输出只有一行,D,表示二者“相遇”的最短时间。当然,如果无法相遇则输出“Peace!”

Sample Input

3 3
1 2 1
2 3 1
1 3 1
1 3

Sample Output

1


解题思路

两遍SPFA,然后枚举相遇点。无视哈希


代码

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int p=29989,air=-117901064;
struct woc{
    int x,y,w,next;
};
int n,m,sum,f[p+1],ls[p+1],f2[p+1],hash[p+1],state[p+1],head,tail,num;
bool v[p+1];
woc line[10001];
int hashmath(int x)
{
    return abs(x)%p;
}
int locate(int x)
{
    int wz=hashmath(x);
    int i=0;
    while (i<p && hash[(wz+i)%p]!=x && hash[(wz+i)%p]!=air)
      i++;
    return (wz+i)%p;
}
void Spfa(int x)//SPFA不解释
{
    memset(f,127/3,sizeof(f));
    state[1]=locate(x);v[state[1]]=true;f[state[1]]=0;
    int w=0;
    head=0;tail=1;
    do
    {
        head=head%p+1;
        w=ls[state[head]];
        while (w!=0)
        {
            if (f[line[w].x]+line[w].w<f[line[w].y])
            {
                f[line[w].y]=f[line[w].x]+line[w].w;
                if (!v[line[w].y])
                {
                    v[line[w].y]=true;
                    tail=tail%p+1;
                    state[tail]=line[w].y;
                }
            }
            w=line[w].next;
        }
        v[state[head]]=false;
    }
    while (head!=tail);
}
void Spfa2(int x)
{
    memset(f2,127/3,sizeof(f2));
    state[1]=locate(x);v[state[1]]=true;f2[state[1]]=0;
    int w=0;
    head=0;tail=1;
    do
    {
        head=head%p+1;
        w=ls[state[head]];
        while (w!=0)
        {
            if (f2[line[w].x]+line[w].w<f2[line[w].y])
            {
                f2[line[w].y]=f2[line[w].x]+line[w].w;
                if (!v[line[w].y])
                {
                    v[line[w].y]=true;
                    tail=tail%p+1;
                    state[tail]=line[w].y;
                }
            }
            w=line[w].next;
        }
        v[state[head]]=false;
    }
    while (head!=tail);
}
int main()
{
    scanf("%d%d",&n,&m);
    for (int i=0;i<p;i++) hash[i]=air;
    int xx,yy,ww,wz1,wz2;
    for (int i=1;i<=m;i++)
    {
        scanf("%d%d%d",&xx,&yy,&ww);
        wz1=locate(xx);wz2=locate(yy);
        if (hash[wz1]==air) hash[wz1]=xx;
        if (hash[wz2]==air) hash[wz2]=yy;
        line[++num].x=wz1;
        line[num].y=wz2;
        line[num].w=ww;
        line[num].next=ls[wz1];
        ls[wz1]=num;
        line[++num].x=wz2;
        line[num].y=wz1;
        line[num].w=ww;
        line[num].next=ls[wz2];
        ls[wz2]=num;//无向图建邻接表
    }
    scanf("%d%d",&xx,&yy);
    Spfa(xx);
    Spfa2(yy);//两遍SPFA
    sum=-air;
    for (int i=0;i<p;i++)//枚举相遇点
    {
        if (hash[i]!=air)
        {
            sum=min(sum,max(f[i],f2[i]));//更新最大值
        }
    }
    if (sum==-air) printf("Peace!");//判断无法相遇
    else printf("%d",sum);
    return 0;
}

转载于:https://www.cnblogs.com/sslwyc/p/9218572.html

资源下载链接为: https://pan.quark.cn/s/22ca96b7bd39 在当今的软件开发领域,自动化构建与发布是提升开发效率和项目质量的关键环节。Jenkins Pipeline作为一种强大的自动化工具,能够有效助力Java项目的快速构建、测试及部署。本文将详细介绍如何利用Jenkins Pipeline实现Java项目的自动化构建与发布。 Jenkins Pipeline简介 Jenkins Pipeline是运行在Jenkins上的一套工作流框架,它将原本分散在单个或多个节点上独立运行的任务串联起来,实现复杂流程的编排与可视化。它是Jenkins 2.X的核心特性之一,推动了Jenkins从持续集成(CI)向持续交付(CD)及DevOps的转变。 创建Pipeline项目 要使用Jenkins Pipeline自动化构建发布Java项目,首先需要创建Pipeline项目。具体步骤如下: 登录Jenkins,点击“新建项”,选择“Pipeline”。 输入项目名称和描述,点击“确定”。 在Pipeline脚本中定义项目字典、发版脚本和预发布脚本。 编写Pipeline脚本 Pipeline脚本是Jenkins Pipeline的核心,用于定义自动化构建和发布的流程。以下是一个简单的Pipeline脚本示例: 在上述脚本中,定义了个阶段:Checkout、Build、Push package和Deploy/Rollback。每个阶段都可以根据实际需求进行配置和调整。 通过Jenkins Pipeline自动化构建发布Java项目,可以显著提升开发效率和项目质量。借助Pipeline,我们能够轻松实现自动化构建、测试和部署,从而提高项目的整体质量和可靠性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值