2000字范文,分享全网优秀范文,学习好帮手!
2000字范文 > SGU 103 Traffic Lights 最短路

SGU 103 Traffic Lights 最短路

时间:2020-09-13 18:44:22

相关推荐

SGU 103 Traffic Lights 最短路

n个点,m条边,给起点和终点,求起点到终点的最小花费,每个点都有两种状态,每个点的每种状态都有一个持续的时间,只有在某条边连接的两个点状态相同时这条边才可走。实际上就是一个带限制的最短路,每次松弛的时候,花费就是边的花费加上最少要等多长时间两个点的颜色会变成相同..如果永远无法相同,这条边就不能走了...思路很简单,时间的处理写起来比较恶心....

#include <iostream>#include <cstdio>#include <algorithm>#include <memory.h>#include <cmath>#include <string>#include <cstring>#include <queue>#include <stack>using namespace std;typedef long long ll;const int inf=(1<<28);const int maxn=330;int n,m,tt,p;int st,ed;struct EDGE{int v,w,next;}edge[30000];int g[maxn];int ne;struct Light{bool type;int res,t1,t2;}light[maxn];int pre[maxn];bool vis[maxn];int dis[maxn];int slove(int src){memset(vis,false,sizeof vis);memset(pre,0,sizeof pre);for (int i=0; i<=n; i++) dis[i]=inf;dis[src]=0;queue<int>q;q.push(src);vis[src]=true;while(!q.empty()){int u,v;int t1,t2;bool f1,f2;u=q.front();int now=dis[u];int cost=0;q.pop();vis[u]=false;for(int j=g[u]; j!=-1; j=edge[j].next){v=edge[j].v;cost=edge[j].w;t1=now-light[u].res;if (t1<0) f1=light[u].type,t1=light[u].res-now;else {t1=t1 % (light[u].t1+light[u].t2);if (!light[u].type){if (t1>=light[u].t2) f1=0,t1=light[u].t1+light[u].t2-t1;else f1=1,t1=light[u].t2-t1;}else{if (t1>=light[u].t1) f1=1,t1=light[u].t1+light[u].t2-t1;else f1=0,t1=light[u].t1-t1;}}t2=now-light[v].res;if (t2<0) f2=light[v].type,t2=light[v].res-now;else{t2=t2 % (light[v].t1+light[v].t2);if (!light[v].type){if (t2>=light[v].t2) f2=0,t2=light[v].t1+light[v].t2-t2;else f2=1,t2=light[v].t2-t2;}else{if (t2>=light[v].t1) f2=1,t2=light[v].t1+light[v].t2-t2;else f2=0,t2=light[v].t1-t2;}}if (f1==f2){if (dis[v]>cost+dis[u]){dis[v]=dis[u]+cost;pre[v]=u;if (!vis[v]){q.push(v);vis[v]=true;}}}else{bool ok=true;if (t1!=t2) cost+=min(t1,t2);else{f1^=1;f2^=1;cost+=t1;if (!f1) t1=light[u].t1;else t1=light[u].t2;if (!f2) t2=light[v].t1;else t2=light[v].t2;if (t1!=t2) cost+=min(t1,t2);else{f1^=1;f2^=1;cost+=t1;if (!f1) t1=light[u].t1;else t1=light[u].t2;if (!f2) t2=light[v].t1;else t2=light[v].t2;if (t1!=t2) cost+=min(t1,t2);else ok=false;}}if (ok){if (dis[v]>dis[u]+cost){dis[v]=dis[u]+cost;pre[v]=u;if (!vis[v]){q.push(v);vis[v]=true;}}}}}}return dis[ed];}void find(int u){if (u==0) return;find(pre[u]);if (u==st)printf("%d",u);else printf(" %d",u);}int main(){// freopen("in.txt","r",stdin);while(~scanf("%d%d",&st,&ed)){scanf("%d%d",&n,&m);char s[5];for (int i=1; i<=n; i++){scanf("%s",&s);light[i].type=(s[0]=='P');scanf("%d%d%d",&light[i].res,&light[i].t1,&light[i].t2);}ne=0;int x,y,z;memset(g,-1,sizeof g);for (int i=1; i<=m; i++){scanf("%d%d%d",&x,&y,&z);edge[ne].v=y;edge[ne].next=g[x];edge[ne].w=z;g[x]=ne;ne++;edge[ne].v=x;edge[ne].next=g[y];edge[ne].w=z;g[y]=ne;ne++;}int out=slove(st);if (out<inf){printf("%d\n",out);find(ed);printf("\n");}else puts("0");}return 0;}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。