题目链接:https://www.patest.cn/contests/gplt/L2-001
代码:
// 这张图是一张 无向 有环 带权 图, 考察一下我们常用的找最短路径的方案,bfs #include <iostream> #include <cstring> using namespace std; const int maxn = 500 + 10; const int maxm = 1000000 + 10; const int inf = 1 << 30; struct Edge { int v; int w; int next; }edge[2 * maxm]; int dist[maxn], head[maxn], people[maxn], pos, pre[maxn], pathNum[maxn], getPeople[maxn]; int n, m; void addEdge(int u, int v, int w){ edge[pos].v = v; edge[pos].w = w; edge[pos].next = head[u]; head[u] = pos; pos++; } void init(){ for(int i = 0; i < maxn; i++) head[i] = -1; for(int i = 0; i < maxn; i++) pre[i] = -1; for(int i = 0; i < maxn; i++) pathNum[i] = 0; for(int i = 0; i < maxn; i++) getPeople[i] = 0; pos = 0; } void Dijkstra(int s, int t){ for(int i = 0; i < n; i++) dist[i] = inf; // 初始化s到其他点的举例 // 初始化s dist[s] = 0; pathNum[s] = 1; getPeople[s] = people[s]; pre[s] = -1; int V[maxn]; // V为0的是Vb集合元素,V为1是Va集合元素 memset(V, 0, sizeof(V)); for(int i = 0; i < n; i++){ // 每次选取Vb中最近的点加入Va(n个点) int u = -1, minimum = inf; for(int j = 0; j < n; j++){ // 选取Vb中dist最近的点 if(!V[j] && dist[j] < minimum){ minimum = dist[j]; u = j; } } V[u] = 1; // 加入Va //用u更新Vb中所有和u相邻的点的距离和其他信息 for(int k = head[u]; k != -1; k = edge[k].next){ int v = edge[k].v; if(!V[v]){ if(dist[v] > edge[k].w + dist[u]){ dist[v] = edge[k].w + dist[u]; pre[v] = u; getPeople[v] = getPeople[u] + people[v]; pathNum[v] = pathNum[u]; } else if(dist[v] == edge[k].w + dist[u]){ pathNum[v] += pathNum[u]; if(getPeople[v] < getPeople[u] + people[v]){ pre[v] = u; getPeople[v] = getPeople[u] + people[v]; } } } } } } void printPath(int s, int t){ int road[maxn]; int p = t; int cnt = 0; while(p != -1){ road[cnt] = p; p = pre[p]; if(p< -1 ||p > n){ cout << "shit"<< endl; break; } cnt++; } for(int i = cnt - 1; i >= 0; i--){ printf("%d", road[i]); if(i != 0) printf(" "); } printf("\n"); } int main(){ //freopen("input.txt", "r", stdin); int s, t; scanf("%d%d%d%d", &n, &m, &s, &t); init(); for(int i = 0; i < n; i++) scanf("%d", &people[i]); for(int i = 0; i < m; i++){ int u, v, w; scanf("%d%d%d", &u, &v, &w); addEdge(u, v, w); addEdge(v, u, w); } Dijkstra(s, t); printf("%d %d\n", pathNum[t], getPeople[t]); printPath(s, t); return 0; }