L2-001. 紧急救援 多条最短路 spfa/dijkstra
2018-02-25 22:35
369 查看
#pragma comment(linker, "/STACK:1024000000,1024000000") #include <bits/stdc++.h> using namespace std; typedef long long ll; const ll inf = 0x3f3f3f3f3f3f3f3f; #define show(a) cout<<#a<<" = "<<a<<endl #define show2(b,c) cout<<#b<<" = "<<b<<" "<<#c<<" = "<<c<<endl #define show3(a,b,c) cout<<#a<<" = "<<a<<" "<<#b<<" = "<<b<<" "<<#c<<" = "<<c<<endl #define show4(a,b,c,d) cout<<#a<<" = "<<a<<" "<<#b<<" = "<<b<<" "<<#c<<" = "<<c<<" "<<#d<<" = "<<d<<endl const int maxn = 100005; #define LOCAL // 建议数组开大一些 int n, m, s, d; int head[505*505], dis[505]; bool vis[505];// 点的总数 int nume = 0; int ans = 0; struct node { int to, cost, next; }e[505*505];// maxn的百倍以上 MAXM表示边的总数 void init() { memset(vis, false, sizeof vis); memset(dis, 0x3f, sizeof dis); memset(head, -1, sizeof head); memset(e, 0, sizeof e); } void add(int u, int v, int w) { e[nume] = (node){v, w, head[u]}; head[u] = nume; nume++; } int numq[505]; int num[505]; // 从出发点到i结点拥有的路的条数 int dui[505]; // 能找到的救援队的数目 边值的sum int pre[505]; // 表示最短路径的前一个结点 int a[505]; // 每个结点的权值 bool spfa(int st, int ed) { int to, cost, now; /***/ queue<int> q; q.push(st); dis[st] = 0; vis[st] = true; /***/ num[st] = 1; dui[st] = a[st]; while( !q.empty() ) { /***/ now = q.front(); q.pop(); vis[now] = false; /***/ for(int i = head[now]; ~i; i = e[i].next ) { to = e[i].to; cost = e[i].cost; if( dis[to] > dis[now] + cost ) { dis[to] = dis[now] + cost; // num[to] = num[now]; // == dui[to] = dui[now] + a[to]; pre[to] = now; if( !vis[to] ) { numq[to]++; if( numq[to] > n) return true; vis[to] = true; q.push(to); } } else if( dis[to] == dis[now] + cost) { // num[to] = num[to] + num[now]; // += if( dui[to] < dui[now] + a[to]) { dui[to] = dui[now] + a[to]; pre[to] = now; if( !vis[to] ) { numq[to]++; if( numq[to] > n) return true; vis[to] = true; q.push(to); } } } } } ans = dis[ed]; } int numd = 0; void dfs(int now) {// 计算最短路的条数 if( now == d ) {numd++; return;} for(int i = head[now]; ~i; i = e[i].next ){ int to = e[i].to; int cost = e[i].cost; if( !vis[to] && dis[to] == dis[now] + cost)// 满足是最短路 { vis[to] = 1; dfs(to); vis[to] = 0; } } } void print(int x) { if( x == s ) {cout << x; return; } print(pre[x]); cout << ' ' << x; } int main() { cin.tie(0); ios::sync_with_stdio(false); init(); cin >> n >> m >> s >> d; for(int i = 0; i < n; i++) cin >> a[i]; int u, v, w; for(int i = 1; i <= m; i++) { cin >> u >> v >> w; add(u, v, w); add(v, u, w); } spfa(s, d); // cout << ans << endl; memset(vis, 0, sizeof(vis)); dfs(s); cout << numd << ' ' << dui[d] << endl; // cout << num[d] << ' ' << dui[d] << endl; print(d); }
#include <cstdio> #include <algorithm> using namespace std; int n, m, c1, c2; int dis[510], weight[510], e[510][510], num[510], w[510], pre[510]; bool visit[510]; const int inf = 99999999; void printPath(int v) { if(v == c1) { printf("%d", v); return ; } printPath(pre[v]); printf(" %d", v); } int main() { scanf("%d%d%d%d", &n, &m, &c1, &c2); for(int i = 0; i < n; i++) scanf("%d", &weight[i]); fill(e[0], e[0] + 510 * 510, inf); fill(dis, dis + 510, inf); int a, b, c; for(int i = 0; i < m; i++) { scanf("%d%d%d", &a, &b, &c); e[a][b] = c; e[b][a] = c; } dis[c1] = 0; w[c1] = weight[c1]; num[c1] = 1; for(int i = 0; i < n; i++) { int u = -1, minn = inf; for(int j = 0; j < n; j++) { if(visit[j] == false && dis[j] < minn) { u = j; minn = dis[j]; } } if(u == -1) break; visit[u] = true; for(int v = 0; v < n; v++) { if(visit[v] == false && e[u][v] != inf) { if(dis[u] + e[u][v] < dis[v]) { dis[v] = dis[u] + e[u][v]; num[v] = num[u]; w[v] = w[u] + weight[v]; pre[v] = u; } else if(dis[u] + e[u][v] == dis[v]) { num[v] = num[v] + num[u]; if(w[u] + weight[v] > w[v]) { w[v] = w[u] + weight[v]; pre[v] = u; } } } } } printf("%d %d\n", num[c2], w[c2]); printPath(c2); return 0; }
相关文章推荐
- [PAT L2-001] 紧急救援(spfa,最短路计数, dp)
- PAT L2-001. 紧急救援 (最短路变形 Dijkstra + 记录路径)
- L2-001. 紧急救援(多级最短路 spfa)
- L2-001. 紧急救援(最短路dijkstra)
- PAT 团体程序设计天梯赛-练习集 L2-001. 紧急救援 【dijkstra】
- L2-001. 紧急救援(dijkstra)
- PAT L2-001 紧急救援 dijikstra 最短路
- CCCC题集 L2-001. 紧急救援 (SPFA/DIJ + 计数 + 路径打印
- CCCC - 天梯赛 - L2-001. 紧急救援 - 最短路(DJS)
- L2-001. 紧急救援 dijkstra,适合模版
- L2-001. 紧急救援(最短路dij+路径记录)(模板)
- PAT L2-001. 紧急救援(Dijkstra + 记录路径)
- L2-001. 紧急救援 (最短路扩展)
- 【最短路-spfa算法+dfs】L2-001. 紧急救援
- L2-001. 紧急救援(dijkstra+dfs)
- PAT L2-001. 紧急救援(扩展dijkstra)
- L2-001. 紧急救援(最短路)
- L2-001. 紧急救援【最短路+dfs】
- L2-001. 紧急救援 SPFA+记录路径,统计最短路
- L2-001. 紧急救援(dijkstra)