• [PAT L2-001] 紧急救援(spfa,最短路计数, dp)


    题目链接:https://www.patest.cn/contests/gplt/L2-001

    用一个数组dp(i,j)表示到i点的时候的最短路个数,dp(i,0)表示在松弛操作时已经更新了最短路的个数,dp(i,1)表示未更新。

    当在松弛操作d(v) > d(u) + w的时候是一定会被更新的,并且最短路有且仅有这么一条,那么更新dp(v,1)=dp(v,0),dp(v,1)=dp(u,0)。

    若d(v) = d(u) + w的时候,说明这个点可以从两条边过来,并且路径都是最短的。那么会被更新,dp(v,1)=dp(v,0),同时把之前到u点的最短路条数更新到v上,dp(v,0)+=(dp(u,0)-dp(u,1))。

    关于救援队的计数,每当走到一个点若进行了松弛操作,就更新一下最大值就行了。假如d[v] == d[u] + w还要考虑这两条最短路上哪个点的救援队多,再更新。

    关于路径,在更新救援队数量的时候记住上一个点,最后输出时递归即可。

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 #define fr first
      4 #define sc second
      5 #define cl clear
      6 #define BUG puts("here!!!")
      7 #define W(a) while(a--)
      8 #define pb(a) push_back(a)
      9 #define Rint(a) scanf("%d", &a)
     10 #define Rll(a) scanf("%lld", &a)
     11 #define Rs(a) scanf("%s", a)
     12 #define Cin(a) cin >> a
     13 #define FRead() freopen("in", "r", stdin)
     14 #define FWrite() freopen("out", "w", stdout)
     15 #define Rep(i, len) for(int i = 0; i < (len); i++)
     16 #define For(i, a, len) for(int i = (a); i < (len); i++)
     17 #define Cls(a) memset((a), 0, sizeof(a))
     18 #define Clr(a, x) memset((a), (x), sizeof(a))
     19 #define Full(a) memset((a), 0x7f7f7f, sizeof(a))
     20 #define lrt rt << 1
     21 #define rrt rt << 1 | 1
     22 #define pi 3.14159265359
     23 #define RT return
     24 #define lowbit(x) x & (-x)
     25 #define onenum(x) __builtin_popcount(x)
     26 typedef long long LL;
     27 typedef long double LD;
     28 typedef unsigned long long ULL;
     29 typedef pair<int, int> pii;
     30 typedef pair<string, int> psi;
     31 typedef pair<LL, LL> pll;
     32 typedef map<string, int> msi;
     33 typedef vector<int> vi;
     34 typedef vector<LL> vl;
     35 typedef vector<vl> vvl;
     36 typedef vector<bool> vb;
     37 
     38 const int maxn = 600;
     39 const int maxm = maxn * maxn;
     40 const int inf = 0x7f7f7f7f;
     41 typedef struct Edge {
     42   int v, w;
     43   int next;
     44   Edge() { next = -1; }
     45 }Edge;
     46 
     47 int n, m, s, t;
     48 Edge edge[maxm];
     49 int head[maxm], ecnt;
     50 int pre[maxm], dp[maxm][2];
     51 int d[maxm], x[maxm], y[maxm];
     52 queue<int> q;
     53 bool vis[maxn];
     54 int u, v, w;
     55 
     56 void adde(int u, int v, int w) {
     57   edge[ecnt].v = v; edge[ecnt].w = w;
     58   edge[ecnt].next = head[u]; head[u] = ecnt++;
     59 }
     60 
     61 void init() {
     62   Clr(head, -1); ecnt = 0; Cls(vis);
     63   Cls(edge); Cls(dp); Clr(pre, -1);
     64   Rep(i, n) {
     65     Rint(x[i]);
     66     y[i] = x[i];
     67   }
     68   Rep(i, m) {
     69     Rint(u); Rint(v); Rint(w);
     70     adde(u,v,w); adde(v,u,w);
     71   }
     72 }
     73 
     74 void spfa(int s) {
     75   while(!q.empty()) q.pop();
     76   Rep(i, n+1) d[i] = inf;
     77   d[s] = 0; q.push(s); dp[s][0] = 1;
     78   vis[s] = 1;
     79   while(!q.empty()) {
     80     int u = q.front(); q.pop(); vis[u] = 0;
     81     for(int i = head[u]; ~i; i=edge[i].next) {
     82       int v = edge[i].v;
     83       int w = edge[i].w;
     84       if(v == u) continue;
     85       if(d[v] > d[u] + w) {
     86         d[v] = d[u] + w;
     87         if(!vis[v]) vis[v] = 1, q.push(v);
     88         pre[v] = u;
     89         y[v] = y[u] + x[v];
     90         dp[v][1] = dp[v][0];
     91         dp[v][0] = dp[u][0];
     92       }
     93       else if(d[v] == d[u] + w) {
     94         if(!vis[v]) vis[v] = 1, q.push(v);
     95         if(y[v] < y[u] + x[v]) {
     96           y[v] = y[u] + x[v];
     97           pre[v] = u;
     98         }
     99         dp[v][1] = dp[v][0];
    100         dp[v][0] += (dp[u][0] - dp[u][1]);
    101       }
    102     }
    103   }
    104 }
    105 
    106 void dfs(int u) {
    107   if(pre[u] == -1) return;
    108   dfs(pre[u]);
    109   printf("%d ", pre[u]);
    110 }
    111 
    112 signed main(){
    113   //FRead();
    114   while(~scanf("%d%d%d%d",&n,&m,&s,&t)) {
    115     init();
    116     spfa(s);
    117     printf("%d %d
    ",dp[t][0], y[t]);
    118     dfs(t); printf("%d
    ", t);
    119   }
    120   RT 0;
    121 }
  • 相关阅读:
    第二阶段冲刺7
    第二阶段冲刺6
    课后作业02需求分析
    阅读计划
    个人总结
    第十六周学习进度条
    第十五周学习进度条
    《梦断代码》阅读笔记03
    《梦断代码》阅读笔记02
    《梦断代码》阅读笔记01
  • 原文地址:https://www.cnblogs.com/kirai/p/5885197.html
Copyright © 2020-2023  润新知