您的位置:首页 > 其它

UVA 12661 Funny Car Racing 有趣的赛车比赛(最短路,变形)

2015-07-16 17:08 621 查看
题意:赛道有n个交叉点,和m条单向路径(有重边),每条路都是周期性关闭的,且通过仍需一段时间。在比赛开始时,所有道路刚好打开,选择进入该道路必须满足“在打开的时间段进入,在关闭之前出来”,即不可在路上逗留,但是可以在交叉点逗留。问到达终点的时间要多少?

思路:最短路,而且正权,用Dijkstra+优先队列够了。主要的难点在计算是否可以进入该路段,画图清晰点。

#include <bits/stdc++.h>
#define LL long long
#define pii pair<int,int>
#define INF 0x7f7f7f7f
using namespace std;
const int N=50000+100;
vector<int> vect[320];

struct node
{
int from;
int to;
int a;
int b;
int len;

}edge
;
int edge_cnt;

void add_node(int u,int v,int a,int b,int t)
{
edge[edge_cnt].from=u;
edge[edge_cnt].to=v;
edge[edge_cnt].a=a;
edge[edge_cnt].b=b;
edge[edge_cnt].len=t;
vect[u].push_back(edge_cnt++);
}

int dis[320];
bool vis[320];

int Dijkstra(int s,int e)
{
memset(vis,0,sizeof(vis));
memset(dis,0x7f,sizeof(dis));
priority_queue<pii, vector<pii>, greater<pii> > que;
que.push(make_pair(0,s));
dis[s]=0;

while(!que.empty())     //每次用一个点来更新别人
{
int x=que.top().second; que.pop();
if(vis[x])  continue;   //遍历过
vis[x]=1;
for(int i=0; i<vect[x].size(); i++)
{
node e=edge[vect[x][i]];
if( dis[x]%(e.a+e.b)+e.len<=e.a
&& dis[e.to]>dis[x]+e.len )  //在可通过时间段
{
dis[e.to]=dis[x]+e.len;
que.push(make_pair(dis[e.to],e.to));
}
else if( dis[e.to]>dis[x]+e.len+ (e.a+e.b-dis[x]%(e.a+e.b))  )    //要等待
{
dis[e.to]=dis[x]+e.len+ (e.a+e.b-dis[x]%(e.a+e.b)) ;
que.push(make_pair(dis[e.to],e.to));
}
}
}
return dis[e];
}

int main()
{

freopen("input.txt", "r", stdin);

int n, m, s, t, u, v, a, b, tt, j=0;
while(~scanf("%d%d%d%d",&n,&m,&s,&t))
{
for(int i=0; i<=n; i++) vect[i].clear();
memset(edge,0,sizeof(edge));
edge_cnt=0;

for(int i=0; i<m; i++)
{
scanf("%d %d %d %d %d", &u, &v, &a, &b, &tt );
if(a>=tt)   add_node(u, v, a, b, tt);//去掉废路
}
printf("Case %d: %d\n", ++j, Dijkstra(s,t));
}
return 0;
}


AC代码
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: