标签:csharp ace des wait add 判断 define problem 最短路问题
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\n",cas++,dis[T]);
}
return 0;
}
标签:csharp ace des wait add 判断 define problem 最短路问题
原文地址:https://www.cnblogs.com/DF-yimeng/p/9742446.html