POJ1158 城市交通Traffic lights IOI 1999 (最短路)

本文介绍了解决POJ1158城市交通问题的方法,这是一个基于最短路径算法的问题。文章详细解释了如何构建模型,并提供了一个具体的C++实现示例。

POJ1158 城市交通Traffic lights IOI 1999 (最短路)

 (1) 问题描述(probolem)

      在d城里交通的安排不同寻常,城中有路口和路口之间的道路,再任意两个不同的路口之间之多有一条道路。从任何一个路口出发,不可能不经过其他路口直接回到该路口。在同一条路道上反正两个方向所需要的通过时间是相同的。在每个路口上只有一盏信号灯,信号灯的颜色在蓝色和紫色之间有规律的交替变化:蓝色有特定的持续时间,紫色也有特定的持续时间,再任意一条道路的两个路口之间,当且仅当这两个路口的信号灯在同一时刻颜色相同时,车辆才被允许实力一个路口驶向另一个路口。如果车辆到达一个路口时,该路口的信号灯正在切换,那么车辆必须组收信号灯的信号。车辆可以在路口等待。你拿到城市地图会显示出以下信息:

所有道路的通过时间(整数)

每一个路口上信号灯两种颜色信号各自的持续时间(整数)

枚一个路口的信号灯得出初始颜色及其发生变化之前的保持时间

你的任务是找出一条路径,使得车辆在交通开始时,用最短的时间,从指定的出发路口到达到指定的目的路口。假设有超过这一条这样的路径,你只需找出一条即可。

(2)假设条件(assumptions)

       2<=n<=300,这里n是路口的数量,路口用数字1至n标号。

       1<=m<=14,000,这里m是道路的数量。

       1<=<=100,这里lij是从路口i到路口j所需要的时间。

       1 £ tic£ 100,这里tic是路口i的信号灯显示颜色c的持续时间。下标c为B,或P,分别代表蓝色和紫色。

       1  £ ric£ tic这里ric是路口i信号灯初始颜色c的保持时间。

(3)输入(input)

       输入是名为lights.inp的正式文件(text file).

          第一行保包含两个数:出发路口和目的路口的标号

          第二行业包含两个数:N,M.

          以下N行包行N个路口的信息,输入文件的第(I+2)行是关于路口I的信息:其中Ci

或是B,或是P,表示路口的信号灯的初始颜色;ricCi颜色的保持时间;tIb是蓝色的持续时间,

tiP是紫颜色的持续时间。

最后m行包含m条道路的信息,每一行有三个数:i, j, lij分别是该道路所连接的两个路口的标号及车辆通过时间。

(4)输出(output)

       输出文件必须是名为lights.out的正文文件(text file)

       如果所搜索的路径存在,则: 

           第一行包含从出发路口经最捷路径到目的路口所需要的时间。

           第二行包含你所发现的最捷路径所经过路口的标号序列,你必须按通过的顺序输出路口的标号。因此,该行的第一个数应是出发路口的标号,而最后一个数则应是目的路口的标号。

       如果所搜索的路径不存在,则:

           输出文件只有一行,该行知包含一个整数0

(5)例子(example)

lights.inp                        lights.out:

 

    
 

1 4

4 5

B 2 16 99

P 6 32 13

P 2 8 7 4

P 38 96 49

1 2 4

1 3 40

2 3 75

2 4 76

3 4 77

 

 
  

127

1 2 4

 
 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

解题报告

这个题构建最短路模型比较恶心。首先,在读入边的时候判断那条路永远不可能走,即灯变化的周期互相错开。之后,在最短路判断时要判断颜色是否一样,如果一样,就直接松弛,否者就计算至少要多久才会颜色一样。再判断是否可以松弛。

#include<bits/stdc++.h>
#define Pair pair<int,int>
#define MAXN 400+10
#define MAXM 40000+1
using namespace std;
int n,m,num,head[MAXN],s,t,pre[MAXN],dis[MAXN],v[MAXM];
int bian[MAXM],ans[MAXN];
struct Edge{
    int dis,next,to,exi,from;
}edge[MAXM];
struct Crossing{
    int co,tc,tp,tb;
}c[MAXN];
void add(int from,int to,int dis)
{
    edge[++num].next=head[from];
    edge[num].to=to;
    edge[num].dis=dis;
    edge[num].from=from;
    head[from]=num;
    edge[num].exi=1;
}
int color(int x,int t)
{
    int q=t-c[x].tc,r=q%(c[x].tp+c[x].tb);
    if(q<0) 
        return c[x].co;
    if(c[x].co==1)
    {
        if(r<c[x].tp) return 2;
        else if(r>=c[x].tp) return 1;
    }else
    if(c[x].co==2)
    {
        if(r<c[x].tb) return 1;
        else if(r>=c[x].tb) return 2;
    }
}
void dij()
{
    memset(dis,0,sizeof(dis));
    memset(pre,0,sizeof(pre));
    memset(v,0,sizeof(v));
    priority_queue<Pair,vector<Pair>,greater<Pair> > h;
    for(int i=1;i<=n;i++) dis[i]=99999999;
    dis[s]=0;
    h.push(Pair(dis[s],s));
    while(h.size()>0)
    {
        int k=h.top().second;h.pop();
        if(v[k]) continue;
        v[k]=1;
        for(int i=head[k];i;i=edge[i].next)
        if(dis[k]+edge[i].dis<dis[edge[i].to])
        {
            int d1=dis[edge[i].to],d2=0,dd=dis[edge[i].to]-dis[k],flag=0;
            int x=edge[i].to,y=edge[i].from;
            if(color(edge[i].to,dis[k])==color(edge[i].from,dis[k]))
                d2=dis[k]+edge[i].dis,flag=1;
            else
                for(int j=dis[k];j<=dis[edge[i].to];j++)
                {
                    if(color(edge[i].to,j)==color(edge[i].from,j)) 
                    {d2=j+edge[i].dis;flag=1;break;}
                }
            if(flag==1&&d2<dis[edge[i].to])
            {
                dis[edge[i].to]=d2;
                pre[edge[i].to]=i;
                h.push(Pair(d2,edge[i].to));
            }
        }
    }
}

int main()
{

    scanf("%d%d%d%d",&s,&t,&n,&m);
    for(int i=1;i<=n;i++)
    {
        char k[10];
        scanf("%s%d%d%d",k,&c[i].tc,&c[i].tb,&c[i].tp);
        if(k[0]=='B') c[i].co=1;
        else if(k[0]=='P') c[i].co=2;
    }
    for(int i=1;i<=m;i++)
    {
        int x,y,z,e=0;
        scanf("%d%d%d",&x,&y,&z);
        if(c[x].tp==c[y].tb&&c[y].tp==c[x].tb)
        {
            if(c[x].tc==c[y].tc&&c[x].co!=c[y].co) e=1;
            else if(c[x].tc!=c[y].tc&&abs(c[x].tc-c[y].tc)%(c[x].tp+c[x].tb)==0) e=1;
            else if(c[x].tc==c[y].tc&&abs(c[x].tc-c[y].tc)%(c[x].tp+c[x].tb)==c[x].tb) e=1;
            else if(c[x].tc==c[y].tc&&abs(c[x].tc-c[y].tc)%(c[x].tp+c[x].tb)==c[x].tp) e=1;            
        }
        if(!e)
        add(x,y,z),
        add(y,x,z);
    }
    
    dij();
    if(dis[t]==99999999) {printf("0\n");return 0;}
    printf("%d\n",dis[t]);
    for(int i=pre[t];i;i=pre[edge[i].from])
        ans[++ans[0]]=edge[i].from;
    for(int i=ans[0];i>=1;i--)
    {
        printf("%d ",ans[i]);
    }printf("%d\n",t);
    return 0;
}

 

转载于:https://www.cnblogs.com/yangyaojia/p/6346507.html

【源码免费下载链接】:https://renmaiwang.cn/s/uwa75 在计算机领域中,DLL(动态链接库)文件是一种用于共享功能的资源,在Windows操作系统中被广泛使用。shell360ext.dll是与360安全卫士相关的DLL文件,主要为系统提供扩展功能。然而,在某些情况下,用户可能需要删除该DLL档案以解决冲突、感染或误删等问题。本文将深入探讨如何安全且高效地删除shell360ext.dll,并分析其可能导致的问题及应对措施。在执行删除操作前,请确保已备份重要数据并充分了解潜在风险。 为了彻底解决与 shell360ext.dll 相关的问题,本文将详细说明如何安全且高效地进行删除操作,并探讨潜在问题及应对策略。首先需要终止所有使用该DLL档案的进程。通过打开任务管理器(按Ctrl+Shift+Esc),用户可以找到相关进程并将其终止。其次,建议在进行系统修改前备份重要数据以避免意外丢失。 接下来,请确定 shell360ext.dll 的具体位置。通常,这些DLL文件位于Windows系统的System32目录下,例如"C:\Windows\System32"。使用搜索功能定位该文件的位置。一旦找到该档案后,即可开始删除操作。右键点击shell360ext.dll,在弹出的菜单中选择“删除”或将其拖入回收站。 在完成删除操作之前,请务必清理与之相关的注册表条目。通过调用注册表编辑器(regedit.exe),用户应谨慎地清除所有涉及该DLL档案的注册表项,以避免潜在系统问题。后,重启计算机以确保更改生效。 需要注意的是,手动处理DLL文件和注册表操作可能带来风险,不熟悉相关操作的用户应格外谨慎。如果担心误操作导致系统异常,请考虑使用专业的卸载工具或联系技术支持寻求帮助。此外,在删除shell360ext.dll后,若发现系统运行不稳定或出现错误,
内容概要:本文详细介绍了一个基于C++开发的科技学院校园二手商品交易系统的设计与实现。系统旨在解决传统校园二手交易中存在的信息不对称、交易不安全、流程繁琐等问题,通过构建一个高效、稳定、安全的在线平台,实现商品信息发布、搜索、交流、交易及管理的全流程数字化。项目采用C++语言保障系统性能与并发处理能力,具备智能推荐、商品管理、第三方支付集成、用户社交互动、信息安全防护等核心功能,并针对系统性能、安全性、用户体验、信息实时性、法律合规及交易纠纷等挑战提出相应解决方案。系统兼具实用性与技术创新性,支持后续功能扩展。; 适合人群:具备一定C++编程基础的计算机相关专业学生、软件开发初学者及对校园信息化系统开发感兴趣的开发者。; 使用场景及目标:①用于高校内部二手物品交易场景,提升资源利用率与交易安全性;②作为C++大型项目实践案例,帮助开发者掌握系统设计、数据库管理、多线程处理、安全机制等关键技术;③为校园智能化管理系统提供可复用的技术架构参考。; 阅读建议:建议结合文中提到的功能模块与示例代码深入理解系统架构设计思路,重点关注智能推荐、支付集成与安全机制的实现逻辑,并可通过联系作者获取完整代码与GUI设计资料进行动手实践。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值