您的位置:首页 > 其它

例题11-11 赛车比赛 单源最短路 spfa

2017-08-09 10:18 253 查看
最短路问题加上了一个条件,处理下开门和关门的时间即可。

#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
#include<string>
#include<cstring>
#include<cstdio>
const int maxn=100005;
const int INF=0x3f3f3f3f;
typedef long long LL;
using namespace std;
struct Edge
{
int e,a,b,t; //e是终点
Edge(){}
Edge(int _e,int _a,int _b,int _t):e(_e),a(_a),b(_b),t(_t){}
};
vector<Edge> edges[maxn];
int dist[maxn];
int vis[maxn];
int N,M,S,T;
int spfa()
{
memset(vis,0,sizeof(vis));
memset(dist,INF,sizeof(dist));
queue<int> q;
q.push(S);
dist[S]=0;
vis[S]=1;
while(!q.empty())
{
int s=q.front();q.pop();
vis[s]=0;
for(int i=0;i<edges[s].size();i++)
{
int e=edges[s][i].e;
int a=edges[s][i].a;
int b=edges[s][i].b;
int t=edges[s][i].t;
int now=dist[s]%(a+b); //当前相对于这条路的时间
if(a-now>=t) //如果能通过
{
if(dist[e]>dist[s]+t)
{
dist[e]=dist[s]+t;
if(!vis[e]){vis[e]=1;q.push(e);}
}
}
else //不能通过
{
int tmp=dist[s]+t+(a+b)-now; //(a+b)-now为等待时间,要等一个回合,而当前时间为now,所以等待了(a+b)-now
if(dist[e]>tmp)
{
dist[e]=tmp;
if(!vis[e]){vis[e]=1;q.push(e);}
}

}

}
}
return dist[T];
}
int main()
{
// freopen("E:\\ACM\\test.txt","r",stdin);
int Case=1;
while(cin>>N>>M>>S>>T)
{
for(int i=0;i<maxn;i++) edges[i].clear();

int u,v,a,b,t;

for(int i=0;i<M;i++)
{
cin>>u>>v>>a>>b>>t;
if(a>=t) edges[u].push_back(Edge(v,a,b,t)); //如果打开时间a都小于通过时间t,那么这条路肯定过不了
}
printf("Case %d: %d\n",Case++,spfa());
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ACM UVA 12661 最短路