题意: 给出一个地图,起点 s,终点 t,和一个数 x,求出s 到 t 的最短路,且经过的路的条数是 x 的倍数。
分析: 可以看成是二维的最短路,在 原dijkstra的基础上修改,从一个点到另一个点走的边数如果是 d,
那么从这个点到另一个点走的边数为 d+1, 只要对 X 取模,便能求出从 s 到 t 经过 x 的倍
数边的最短路径。
#include<stdio.h> #include<string.h> const long long INF=9999999999; long long g[102][102]; long long d[102][11]; int v[102][11]; int main() { // freopen("D:ce2.txt","r",stdin); int t,T,n,m,i,j,k,x,p,q,flag; int s,u,next,cur; long long tmp,w; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); for(i=0;i<n;i++) { for(j=0;j<11;j++) d[i][j]=INF; for(j=0;j<n;j++) g[i][j]=INF; } memset(v,0,sizeof(v)); while(m--) { scanf("%d%d%lld",&p,&q,&w); if(w<g[p][q]) g[p][q]=w; } scanf("%d%d%d",&s,&t,&x); flag=0; d[s][0]=0; while(1) { tmp=INF; u=-1; for(j=0;j<n;j++) for(k=0;k<x;k++) if(!v[j][k]&&d[j][k]<tmp) // 当前的路径数是k,由当前点得到的新的边加上 { // 之前的边数 就是 cur+1 tmp=d[j][k]; u=j; cur=k; next=(cur+1)%x; } if(u==-1) break; v[u][cur]=1; if(v[t][0]) break; for(j=0;j<n;j++) if(!v[j][next]&&d[u][cur]+g[u][j]<d[j][next]) // 下一个点由于是由当前经过 cur 条边得到的 d[j][next]=d[u][cur]+g[u][j]; // 所以松弛之后 下一个点经过的 边数就是 next = cur+1 } if(d[t][0]!=INF) printf("%lld\n",d[t][0]); else printf("No Answer!\n"); } return 0; }