题意: 给出一个地图,起点 s,终点 t,和一个数 x,求出s 到 t 的最短路,且经过的路的条数是 x 的倍数。
View Code
//哈理工OJ 1066. acm.hrbust.edu.cn //二维dijkstra #include<stdio.h> #include<string.h> #include<algorithm> using namespace std; #define llong long long const int MAXN = 105; const llong INF = -1ULL >> 1; llong n, m, s, t, x; //题中变量。 llong Edge[MAXN][MAXN]; //邻接阵。 llong dist[MAXN][11]; //最短距离。 bool S[MAXN][11]; //标记数组。 void dijkstra() { for(int i = 0; i < n; i++) { for(int k = 0; k < x; k++) { dist[i][k] = INF; } } memset(S, 0, sizeof(S)); dist[s][0] = 0; while(1) { llong minx = INF; int u = -1; //选择当前集合中具有最短路径的顶点。 int c = -1; for(int i = 0; i < n; i++) { for(int k = 0; k < x; k++) { if(!S[i][k] && dist[i][k] < minx) { u = i; c = k; minx = dist[i][k]; } } } //如果没有找到最短路径的顶点 或者 源点到终点t的路径以求得, 跳出循环。 if(u == -1 || S[t][0]) { break; } //将该顶点标记,表示它的最短路径以求得。 S[u][c] = 1; int sum = (c+1) % x; //如果到一个点经过的路径是c条, 那么经过下一个点的路径是c+1条。 //因为题意说是x的倍数,所以对x取模。 for(int i = 0; i < n; i++) { if( !S[i][sum] && Edge[u][i] < INF && minx + Edge[u][i] < dist[i][sum]) { dist[i][sum] = Edge[u][i] + minx; } } } } int main() { int nTest; scanf("%d", &nTest); while( nTest-- ) { scanf("%lld %lld", &n, &m); for(int i = 0; i <= n; i++) { for(int j = 0; j <= n; j++) { Edge[i][j] = INF; } } for(int i = 1; i <= m; i++) { llong u, v, len; scanf("%lld %lld %lld", &u, &v, &len); //本题有重边。 if(len < Edge[u][v]) { Edge[u][v] = len; } } scanf("%lld %lld %lld", &s, &t, &x); dijkstra(); if(dist[t][0] < INF) { printf("%lld\n", dist[t][0]); } else { printf("No Answer!\n"); } } return 0; }