PAT 甲级 1003
2018-01-27 19:10
501 查看
PAT 1003
题目介绍:
给出城市的连接状况和每个城市的救援队伍的数量。给定起点和终点,求出起点到终点最短路径的个数,以及找出一条可以包含救援队最多的最短路径,输出最多可以累计的救援队的数目。题目思路:
本题目很明显是一个Dijkstra的最短路算法,但是题目的真正考察点在于求解最短路的个数和在多条最短路径上求解出累计救援队伍数目最多的个数。路的条数和救援队伍的数目都采用累计求和的思想。Dijkstra算法的核心是把结点划分成两个集合:已经求得最短路径的和未求得最短路径的。这个关系用一个用一个不等式来维护,具体参考算法导论有关章节。在这里的最短路算法,利用到了堆优化,每次从最小堆中取出两个集合间的最短距离进行不等关系的维护。如果可以缩短当前u->v的路径,那么,
dist[v]=dist[u]+w(u,v);
num[v]=team[v]+num[v]表示
v的救援队伍的总数是v自己的加上u之前累加的;
road[v]=road[u]是因为u->v只有一条路,那么从原点到v还是等于从原点到u的数目。
如果遇到了
dist[v]=dist[u]+w(u,v)的情况,说明还有还有从原点到v不经过u的路径的长度等于从原点到v经过u的路径的长度;那么,此时的
road[v]肯定要加上
road[u]的,才是更新后的路径的数目,即
road[v]+=road[u]。注意,如果队伍数目的更新条件
num[it->v] <= num[t] + team[it->v],也就是说,如果有更多的队伍数目,才进行更新!
AC代码:
#include <bits/stdc++.h> using namespace std; const int MAXN = 503; // 最大的结点个数 const int INF = 10000000; int N, M, BEGIN, END; // 结点个数,边个数,起点,终点 // team是每个城市的队伍个数,num是最短路上城市累计的个数,dist是最短路径,road是路径累加的个数 int team[MAXN], num[MAXN], dist[MAXN], road[MAXN]; bool flag[MAXN]; // 加入最短路的标记 struct Node { int v, w; }; vector<Node>G[MAXN]; // 建图 struct cmp { // 自定义比较结构 bool operator()(const int& a, const int& b) { return dist[a] > dist[b]; } }; void Create() { int u, v, w; for(int i = 0; i < M; ++i) { cin >> u >> v >> w; Node tmp; tmp.v = v; tmp.w = w; G[u].push_back(tmp); // 注意是无向图!!!!! tmp.v = u; tmp.w = w; G[v].push_back(tmp); } } void Dijkstra(int u) { for(int i = 0; i < N; ++i) { dist[i] = INF; num[i] = team[i]; flag[i] = false; road[i] = 0; } dist[u] = 0; road[u] = 1; priority_queue<int, vector<int>, cmp>Q; Q.push(u); while(!Q.empty()) { int t = Q.top(); Q.pop(); if(flag[t]) { continue; } flag[t] = true; for(auto it = G[t].begin(); it != G[t].end(); it++) { if(flag[it->v]) { continue; } else if(dist[it->v] > dist[t] + it->w) { dist[it->v] = dist[t] + it->w; num[it->v] = team[it->v] + num[t]; road[it->v] = road[t]; Q.push(it->v); } else if(dist[it->v] == dist[t] + it->w ) { if(num[it->v] <= num[t] + team[it->v]) { num[it->v] = num[t] + team[it->v]; } road[it->v] += road[t]; // 路径加1 } } } } int main() { cin >> N >> M >> BEGIN >> END; for(int i = 0; i < N; ++i) { cin >> team[i]; } Create(); Dijkstra(BEGIN); cout << road[END] << " " << num[END]; return 0; }
相关文章推荐
- PAT程序设计考题——甲级1003(Emergency ) C++实现
- PAT甲级C语言.1003. 我要通过!
- PAT(甲级)1003
- PAT甲级1003---迷宫问题(DFS或Dijkstra)
- [PAT-甲级]1003.Emergency
- PAT甲级1003(深搜)
- 浙大PAT甲级-1003
- PAT-甲级-1003
- PAT程序设计练习——甲级1003(任意两个城市最短距离、Floyd最短路径算法)
- pat 甲级 1003
- 浙大Pat | 浙大pat 牛客网甲级 1003 Highest Price in Supply Chain (25)DFS
- pat甲级_路径问题(例题:pat 1003 Emergency (25))
- pat 甲级 1003 Emergency
- 【PAT】甲级1003 - Emergency(最短路)
- PAT 甲级试题1003 Emergency (25) dijkstra变形应用
- PAT甲级 1003
- PAT甲级 1003
- PAT 甲级练习 1003
- pat 甲级 1003
- Pat 1003 甲级