zoukankan      html  css  js  c++  java
  • POJ 3594 Escort of Dr. Who How(最短路+枚举)

    题意:有n个城市道路,每个道路只能再一段区间[b,e]内可行,有给出每条道路的经过时间,问从出发开始时间st到结束最快结束时间en,的差en-st最小是多少。

    思路:由于出发时间是不定的,当然可以用dfs暴搜,不过复杂度是肯定不能承受的,所以我们可以枚举开始时间start,这样就能对每个路段进行限制,在处理路段时,假如到达一个路段的时间为t0,只有满足下列条件,这条路段才是可行的(不包括c>e-b,因为这种情况开始就可以排除) 条件:t0+c <= e,然后经过完这条线路时,此路段结束时间为 max{t0+c,b+c}。

    算法:对出发时间st从小到大枚举,每次bfs,dij求最短路时更新时间差,直到对于一个st*,不存在可行路径,返回最小值,这个值就是答案,我们可以证明对于一个出发时间st,他的解包括了st*的解(st*>st),因为考虑一个st时,我们完全可以延后到st*在出发!所以最后得到的值是最优的。

    PS:话说最近做的枚举题已经超过了图论了.......

    #include <iostream>
    #include
    <cstdio>
    #include
    <algorithm>
    #include
    <memory.h>
    #include
    <cmath>
    #include
    <bitset>
    #include
    <queue>
    #include
    <vector>
    using namespace std;

    const int BORDER = (1<<20)-1;
    const int MAXSIZE = 37;
    const int MAXN = 1105;
    const int INF = 1000000000;
    #define CLR(x,y) memset(x,y,sizeof(x))
    #define ADD(x) x=((x+1)&BORDER)
    #define IN(x) scanf("%d",&x)
    #define OUT(x) printf("%d\n",x)
    #define MIN(m,v) (m)<(v)?(m):(v)
    #define MAX(m,v) (m)>(v)?(m):(v)
    #define ABS(x) ((x)>0?(x):-(x))

    #define SET_NODE(no,a,b) {no.u=a;no.val=b;}

    typedef
    struct{
    int u;
    int val;
    }Node;
    typedef
    struct{
    int v,next;
    int b,e;
    int c;
    }Edge;

    Edge edge[MAXN
    *MAXN];
    Node t_node,node;
    int n,m,s,t,index,mmin,mmax;
    int net[MAXN],tim[MAXN];
    bool visit[MAXN];

    bool operator < (const Node& a,const Node& b)
    {
    return a.val > b.val;
    }
    void add_edge(const int& u,const int& v,const int& b,
    const int& e,const int& c)
    {
    edge[index].v
    = v;
    edge[index].b
    = b;
    edge[index].e
    = e;
    edge[index].c
    = c;
    edge[index].next
    = net[u];
    net[u]
    = index++;
    }
    int init()
    {
    index
    = 0;
    CLR(visit,
    0);
    CLR(net,
    -1);
    CLR(tim,
    127);
    return 0;
    }
    int input()
    {
    int i,j,u,v,b,e,c;
    for(i = 0; i < m; ++i)
    {
    scanf(
    "%d%d%d%d%d",&u,&v,&b,&e,&c);
    if(c > e - b)
    continue;
    add_edge(u,v,b,e,c);
    }
    return 0;
    }
    int bfs(const int& tim_st)
    {
    int u,v,tmp,cur,i;
    priority_queue
    <Node> que;
    while(!que.empty())
    que.pop();
    SET_NODE(t_node,s,tim_st);
    que.push(t_node);
    while( !que.empty())
    {
    node
    = que.top();
    que.pop();
    u
    = node.u;
    cur
    = node.val;
    if(u == t)
    return cur - tim_st;
    for(i = net[u]; i != -1; i = edge[i].next)
    {
    v
    = edge[i].v;
    tmp
    = MAX(cur,edge[i].b);
    tmp
    += edge[i].c;
    if(tmp > edge[i].e)
    continue;
    if(tmp > tim[v])
    continue;
    tim[v]
    = tmp;
    SET_NODE(t_node,v,tmp);
    que.push(t_node);
    }
    }
    return -1;
    }
    int work()
    {
    int i,j,ans,tmp;
    ans
    = INF;
    mmin
    = INF;
    mmax
    = -1;
    for( i = net[s]; i != -1; i = edge[i].next)
    {
    mmin
    = MIN(mmin,edge[i].b);
    mmax
    = MAX(mmax,edge[i].e);
    }
    for( i = mmin; i <= mmax; ++i)
    {
    CLR(tim,
    127);
    tmp
    = bfs(i);
    if(tmp == -1)
    break;
    ans
    = MIN(ans,tmp);
    }
    if(ans == INF)
    printf(
    "Impossible\n");
    else
    OUT(ans);
    return 0;
    }
    int main()
    {
    while(scanf("%d%d%d%d",&n,&m,&s,&t)!=EOF)
    {
    init();
    input();
    work();
    }
    return 0;
    }

  • 相关阅读:
    vue2.0 微信分享
    小程序开发:canvas在画布上滑动,页面跟着滑动问题
    前端AES解密
    vue2上传图片到OSS
    vue给不同环境配置不同打包命令
    vue页面绑定数据,渲染页面时会出现页面闪烁
    解决微信浏览器无法使用window.location.reload刷新页面
    vue列表拖拽组件 vue-dragging
    千万别在Java类的static块里写会抛异常的代码!
    linux shell的一些配置
  • 原文地址:https://www.cnblogs.com/lvpengms/p/1724212.html
Copyright © 2011-2022 走看看