标签:
题目大意:有一个城市的路线图,有N个交叉点,每两个交叉点之间只有一条路,现在想从交点u去交点v,不过这个路的交通比较特别,每个路都有一个交通灯,灯有两种颜色,蓝色和紫色,例如一条路线在交点s,t之间,如果想从s走到t,那么只有等s和t的交通灯的颜色一致的时候才可以从s走,求出来从u到v的最短时间。
分析:比较明显能看出来是一个最短路问题,不过里面夹杂的这个交通灯比较恶心,要随时能求出来两点点下一个相同颜色的时间,如果使用时间去枚举无疑是个比较笨的方法,注意到有个剩余时间,并且交通灯的每种颜色存在的最大值是100,所以可以判断出,一定会有重复情况出现,比如s剩余a,t剩余b,这种状态再次出现不会超过200次蓝紫灯循环,所以只需要枚举200次即可,如果还是找不带相同颜色,那么就说明这条路不能行走。ps.时间内存都比较小,边数比较多,所以邻接矩阵比连接表更省内存,注意有可能会有重边的情况。
代码如下:
=========================================================================================================================
#include<stdio.h> #include<string.h> #include<algorithm> using namespace std; const int MAXN = 307; const int oo = 1e9+7; struct Junction { int op;///等于0是B, 等于1代表P int Last;///剩余时间 int t[2];///两种灯的转换时间 Junction NewOp(int time) {///time时刻的状态 Junction res; if(time >= Last) {///当前时间大于剩余时间,等于的时候也需要转变成下一个灯 time -= Last; time %= (t[0]+t[1]); if(time >= t[op^1]) { res.op = op; res.Last = t[op] - (time-t[op^1]); } else { res.op = op^1; res.Last = t[op^1]-time; } } else { res.op = op; res.Last = Last - time; } res.t[0] = t[0], res.t[1] = t[1]; return res; } int SameColor(Junction a, Junction b) {///两个路灯下个相同颜色最少需要时间,-1表示不可能相同 ///因为中间涉及到值得改变,所以不使用指针 int i, time=0; for(i=0; i<200; i++) { if(a.op == b.op) return time; else if(a.Last >= b.Last) { time += b.Last; a.Last -= b.Last; b.Last = 0; } else if(a.Last < b.Last) { time += a.Last; b.Last -= a.Last; a.Last = 0; } if(a.Last == 0) { a.op ^= 1; a.Last = a.t[a.op]; } if(b.Last == 0) { b.op ^= 1; b.Last = b.t[b.op]; } } return -1; } }; Junction p[MAXN];///交叉点 int N;///交叉点个数 int G[MAXN][MAXN]; void Dij(int start, int end) { int dist[MAXN], path[MAXN]={0}; int visit[MAXN]={0}; for(int i=1; i<=N; i++) dist[i] = oo; dist[start] = 0; for(int t=0; t<N; t++) { int index=start, Min=oo; for(int i=1; i<=N; i++) { if(visit[i] == false && dist[i] < Min) { Min = dist[i]; index = i; } } if(visit[index]) break; visit[index] = true; Junction u = p[index].NewOp(dist[index]), v; for(int i=1; i<=N; i++) { if(!visit[i] && G[index][i] != oo && dist[i]>dist[index]+G[index][i]) { v = p[i].NewOp(dist[index]); int time = u.SameColor(u, v); if(time != -1 && dist[i] > dist[index]+G[index][i]+time) { dist[i] = dist[index] + G[index][i] + time; path[i] = index; } } } } if(dist[end] == oo) printf("0\n"); else { printf("%d\n", dist[end]); int k=0, ans[MAXN]; while(end) { ans[k++] = end; end = path[end]; } for(int i=k-1; i>=0; i--) printf("%d%c", ans[i], i==0?‘\n‘:‘ ‘); } } int main() { int M, start, end; char s[10]; scanf("%d%d%d%d", &start, &end, &N, &M); for(int i=1; i<=N; i++) { scanf("%s%d%d%d", s, &p[i].Last, &p[i].t[0], &p[i].t[1]); p[i].op = (s[0]==‘B‘ ? 0 : 1); } int u, v, len; for(int i=1; i<=N; i++) for(int j=1; j<=N; j++) G[i][j] = oo; while(M--) { scanf("%d%d%d", &u, &v, &len); G[u][v] = G[v][u] = min(G[u][v], len); } Dij(start, end); return 0; }
标签:
原文地址:http://www.cnblogs.com/liuxin13/p/4803450.html