HDU 4522
假设湫湫有可能经过的n个城市分别编号从1到n,湫湫要从城市A回到城市B,购票网站上列出了t辆列车行程,每辆车的行程用一个字符串表示,途径的城市间用+号相连,如1+2+3+5代表一辆从1城市分别经过2,3到达5的火车,湫湫可以从中间任意一站出发和下车(路径是单向的,即必须沿字符串从左到右来走),每个字符串对应着一个整数k,k=0表示该车只有硬座,k=1表示该车有卧铺也有硬座,在整个回家的计划中,同一辆车可以坐无限次,为了中途换车的方便,如果在起点坐的是卧铺,则后面乘坐的车必须全是卧铺,同样的,如果在起点坐的是硬座,则后面乘坐的车必须全是硬座,假设一段(一辆车行程中,两相邻城市间为一段)硬座的不舒适度是D1,一段卧铺的不舒适度是D2,求湫湫回家最小的不舒适度。
因为题目要求只能一直都坐硬卧或一直都坐软卧,所以要2遍最短路。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> #include <cstring> #include <cstdio> using namespace std; const int Max = 209; #define inf 1<<28 #define min(a,b) a<b?a:b int mat[Max][Max]; int map[Max][Max]; char ss[Max*100]; int dis[Max]; bool vis[Max]; int n,m; void dij1(int s) { memset(vis,0,sizeof(vis)); for(int i = 1; i <=n ; i++) dis[i] = mat[s][i]; vis[s] = 1; while(1) { int mmin = inf; int p = -1; for(int i = 1; i <= n; i++) { if(dis[i] < mmin && !vis[i]) { p = i; mmin = dis[i]; } } if(p == -1) break; vis[p] = 1; for(int i = 1; i <= n; i++) { if(!vis[i] && dis[i] > dis[p] + mat[p][i]) dis[i] = dis[p] + mat[p][i]; } } } void dij2(int s) { memset(vis,0,sizeof(vis)); for(int i = 1; i <=n ; i++) dis[i] = map[s][i]; vis[s] = 1; while(1) { int mmin = inf; int p = -1; for(int i = 1; i <= n; i++) { if(dis[i] < mmin && !vis[i]) { p = i; mmin = dis[i]; } } if(p == -1) break; vis[p] = 1; for(int i = 1; i <= n; i++) { if(!vis[i] && dis[i] > dis[p] + map[p][i]) dis[i] = dis[p] + map[p][i]; } } } int main() { int t; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) { mat[i][j] = inf; map[i][j] = inf; } } for(int i=0;i<m;i++) { int x; scanf("%s",ss); scanf("%d",&x); int len = strlen(ss); int s1 = 0,s2 = 0; int j = 0; while(ss[j] != '+') { s1 = s1*10 + ss[j]-'0'; j++; } for(j++; j < len ;j++) { while(ss[j] != '+' && j < len) { s2 = s2*10 + ss[j]-'0'; j++; } if(x == 1) mat[s1][s2] = 1; else mat[s1][s2] = 0; s1 = s2; s2 = 0; } } int v1,v2; int s,e; scanf("%d%d",&v1,&v2); scanf("%d%d",&s,&e); for(int i = 1;i <= n;i++) { for(int j = 1; j <= n; j++) { if(mat[i][j] == 1){ map[i][j] = v2; mat[i][j] = v1; } else if(mat[i][j] == 0) mat[i][j] = v1; } } dij1(s); int ans1 = dis[e]; dij2(s); int ans2 = dis[e]; int ans = min(ans1,ans2); if(ans >= inf) printf("-1\n"); else printf("%d\n",ans); } return 0; }