CCCC题集 L2-001. 紧急救援 (SPFA/DIJ + 计数 + 路径打印
2018-03-28 01:56
363 查看
L2-001. 紧急救援
题目描述
作为一个城市的应急救援队伍的负责人,你有一张特殊的全国地图。在地图上显示有多个分散的城市和一些连接城市的快速道路。每个城市的救援队数量和每一条连接两个城市的快速道路长度都标在地图上。当其他城市有紧急求助电话给你的时候,你的任务是带领你的救援队尽快赶往事发地,同时,一路上召集尽可能多的救援队。输入
输入第一行给出4个正整数N、M、S、D,其中N(2<=N<=500)是城市的个数,顺便假设城市的编号为0~(N-1);M是快速道路的条数;S是出发地的城市编号;D是目的地的城市编号。第二行给出N个正整数,其中第i个数是第i个城市的救援队的数目,数字间以空格分隔。随后的M行中,每行给出一条快速道路的信息,分别是:城市1、城市2、快速道路的长度,中间用空格分开,数字均为整数且不超过500。输入保证救援可行且最优解唯一。输出
第一行输出不同的最短路径的条数和能够召集的最多的救援队数量。第二行输出从S到D的路径中经过的城市编号。数字间以空格分隔,输出首尾不能有多余空格。样例
输入样例: 4 5 0 3 20 30 40 10 0 1 1 1 3 2 0 3 3 0 2 2 2 3 2 输出样例: 2 60 0 1 3
题意
模板题 不过要是这个代码写的好烦 L2的话有点难,,,以后有空把DIJ写法补上
AC代码
#include <iostream> #include <cstring> #include <cstdio> #include <vector> #include <queue> #include <algorithm> using namespace std; #define LL long long #define CLR(a,b) memset(a,(b),sizeof(a)) const int INF = 0x3f3f3f3f; const int MAXN = 1e3+11; struct edge { int v, cost; edge(int _v=0, int _cost=0):v(_v),cost(_cost){} }; vector<edge> E[MAXN]; bool vis[MAXN]; int dis[MAXN], dp[MAXN][2], len[MAXN][MAXN]; int pre[MAXN]; int cs[MAXN],ans[MAXN]; void spfa(int s, int n) { CLR(vis,false); for(int i = 0; i <= n; i++) dis[i] = INF; dis[s] = 0; dp[s][0] = 1; vis[s] = true; queue<int> que; que.push(s); while(!que.empty()) { int u = que.front(); que.pop(); vis[u] = false; if(u == n) continue; for(int i = 0; i < E[u].size(); i++) { int v = E[u][i].v; int cost = E[u][i].cost; if(dis[v] >= dis[u]+cost) { if(dis[v] > dis[u]+cost) { dis[v] = dis[u]+cost; ans[v] = ans[u]+cs[v]; dp[v][1] = dp[v][0]; dp[v][0] = dp[u][0]; pre[v] = u; } else { if(ans[v] < ans[u]+cs[v]) { pre[v] = u; ans[v] = ans[u]+cs[v]; } dp[v][1] = dp[v][0]; dp[v][0] += (dp[u][0]-dp[u][1]); } if(!vis[v]) { que.push(v); vis[v] = true; } } } } } void addedge(int u,int v,int w) { E[u].push_back(edge(v,w)); E[v].push_back(edge(u,w)); } void print(int x) { if(pre[x] != -1) { print(pre[x]); cout << pre[x] << " "; } } int main() { //ios::sync_with_stdio(false); CLR(pre,-1); CLR(ans,0); CLR(dp,0); int n, m, s, d; cin >> n >> m >> s >> d; for(int i = 0; i < n; i++) { cin >> cs[i]; ans[i] = cs[i]; } for(int i = 0; i < m; i++) { int u, v, w; cin >> u >> v >> w; addedge(u,v,w); } spfa(s,n); cout << dp[d][0] << ' ' << ans[d] << endl; print(d); cout << d << endl; return 0; }
相关文章推荐
- [PAT L2-001] 紧急救援(spfa,最短路计数, dp)
- L2-001. 紧急救援 SPFA+记录路径,统计最短路
- L2-001. 紧急救援(多级最短路 spfa)
- 【天梯赛】L2-001. 紧急救援(dijkstra算法找最短路和最短路径数 + 输出路径)
- L2-001. 紧急救援(最短路dij+路径记录)(模板)
- PAT L2-001 紧急救援【最短路径变形】
- PAT天梯赛L2-001. 紧急救援 dijk经典最短路劲+点权最大+记录路径
- L2-001紧急救援(最短路,路径,结点值)
- L2-001. 紧急救援 多条最短路 spfa/dijkstra
- L2-001. 紧急救援(PAT 最短路+记录路径)
- PAT L2-001. 紧急救援(Dijkstra + 记录路径)
- L2-001. 紧急救援---(Dijkstra,记录路径)
- L2-001. 紧急救援(dijkstra+记录路径)
- PAT L2-001. 紧急救援 (最短路变形 Dijkstra + 记录路径)
- CCCC 比赛题目集 L1 - 001 紧急救援 【最大点权和 + 打印路径和路径条数 + 最短路】 好题!!!
- PAT ~ L2-001. 紧急救援 (最短路 + 最短路径条数 + 点权最大 + 路径输出)
- L2-001. 紧急救援(最短路径的条数)
- L2-001. 紧急救援 (Dijkstra最短路径变形)
- L2-001. 紧急救援
- L2-001. 紧急救援