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;
}
原文地址:https://www.cnblogs.com/DF-yimeng/p/9742446.html