您的位置:首页 > 其它

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: