zoukankan      html  css  js  c++  java
  • CSU1333最短路问题SPFA

    fastvj.rainng.com/contest/236779#problem/I

    Description:
      n个点m条路每条路 l,r,t:表示这条路开l秒,关r秒,通过要t秒,问你车辆从s到t最少要多少秒

    Solution:
      (刷着最大流突然看到了我亲爱的最短路,真的是我相见恨晚,而且还是这个专题的最后一题,嘿嘿嘿,拿下)

      考点就是spfa的松弛操作,dis表示当前到now点的时间,你要判断现在t秒能不能通过下一条路,可以的话松弛就是dis[now] + t,不行的话你得等,等到那个路通了再走,dis[now] + wait + t;

      还是比较年轻,存在有的路开通时间小于通过时间,那些边不予考虑!

    Code:

    #include <iostream>
    #include <queue>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define inf  (1 << 28)
    using namespace std;
    const int maxn = 5e4 + 5;
    const int maxm = 5e4 + 5e3;
    struct node{
        int to,l,r,t,pre;
    }e[maxm];
    int id[maxn],cnt;
    //spfa
    int dis[maxn];
    int vis[maxn];
    void init()
    {
        memset(vis,0,sizeof(vis));
        memset(id,-1,sizeof(id));
        cnt = 0;
    }
    void add(int from,int to,int l,int r,int t)
    {
        e[cnt].to = to;
        e[cnt].l = l;
        e[cnt].r = r;
        e[cnt].t = t;
        e[cnt].pre = id[from];
        id[from] = cnt++;
    }
    void spfa(int s,int n)
    {
        for(int i = 0;i <= n;++i)
            dis[i] = inf;
        dis[s] = 0;
        vis[s] = 1;
        queue<int> q;
        q.push(s);
    
        while(q.size())
        {
            int now = q.front();
            q.pop();
            for(int i = id[now];~i;i = e[i].pre)
            {
                int to = e[i].to;
                int t = e[i].t;
                int l = e[i].l;
                int r = e[i].r;
                int tot = l + r;
                int cost;
    
                if((dis[now] % tot) + t <= l)cost = t;
                else cost = r + (l - (dis[now] % tot)) + t;
                if(dis[to] > dis[now] + cost)
                {
                    dis[to] = dis[now] + cost;
                    if(!vis[to])
                    {
                        vis[to] = 1;
                        q.push(to);
                    }
                }
            }
            vis[now] = 0;
        }
        return;
    }
    int main()
    {
        int S,T,n,m;
        int cas = 1;
        while(~scanf("%d%d%d%d",&n,&m,&S,&T))
        {
            init();
            int from,to,l,r,t;
            for(int i = 1;i <= m;++i)
            {
                scanf("%d%d%d%d%d",&from,&to,&l,&r,&t);
                //没考虑到啊!!!!
                if(l>=t)
                    add(from,to,l,r,t);
            }
            spfa(S,n);
            printf("Case %d: %d
    ",cas++,dis[T]);
        }
        return 0;
    }
    
  • 相关阅读:
    flutter 布局
    常见错误
    xpath
    bzoj1485 [HNOI2009]有趣的数列 卡特兰数
    博弈 Nim问题 POJ2234
    bzoj 1014 [JSOI2008]火星人prefix
    codevs 1743 反转卡片 rope or splay
    bzoj 2326 矩阵乘法
    bzoj 1702 贪心,前缀和
    bzoj 1700 Problem Solving 解题 dp
  • 原文地址:https://www.cnblogs.com/DF-yimeng/p/9742446.html
Copyright © 2011-2022 走看看