L2-001 緊急救援 (25分)【新增陣列求最短路數量】【pre陣列記錄最短路徑】

bug生產專家發表於2020-11-28

L2-001 緊急救援 (25分)

這道題,需要求出用vector來做,用陣列來做可能會爆。
dijkstra()就不說什麼,主要是關於新增兩個陣列:

  • 第一:新增num[]陣列,
  • 當兩個路徑的距離相等時,我們要用num[]陣列與之前的加和。
  • 當兩個路徑的距離不同時,我們要更新num[]陣列。
  • 第二:新增pre陣列,這個和迷宮問題是類似的,這裡主要說一下,pre[]陣列的輸出問題
  • 1.可以用遞迴的方式輸出。
  • 2.可以用while迴圈的方式輸出。
//遞迴輸出
void Path(int g)
{
    if (g == s)
    {
        printf("%d", g);
        return;
    }
    Path(pre[g]);
    printf(" %d", g);
    if(g == t)
    puts("");
}
//while迴圈輸出
void Path()
{
    int k = 0;
    int x = t;
    while(x != s)
    {
        a[k ++ ] = x;
        x = pre[x];
    }
    reverse(a, a + k);
    cout << '0' << ' ';
    for(int i = 0; i < k; i ++ )
    {
        if(i != k - 1)
        cout << a[i] << ' ';
        else cout << a[i] << endl;
    }
}

//這個最後會報錯,所以要改成vector來做。

#include <bits/stdc++.h>
 
using namespace std;
const int N = 1e4 + 10, M = N * 2;
int e[M], ne[M], idx, h[N], w[M];
int d1[N], d2[N];
int pre[N];
int n, m, s, t;
int cnt = 0;
int re[N], a[N], sum[N], num[N];
bool vis[N];

typedef pair<int, int> PII;

void add(int a, int b, int c)
{
    e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx ++ ;
}

void dijkstra()
{
    memset(d1, 0x3f, sizeof d1);
    priority_queue<PII, vector<PII>, greater<PII> > q;
    q.push({0, s});
    d1[s] = 0;
    while(q.size())
    {
        PII g = q.top();
        q.pop();
        if(vis[g.second]) continue;
        vis[g.second] = true;
        int ver = g.second, dist = g.first;
        for(int i = h[ver]; ~i; i = ne[i])
        {
            int j = e[i];
            if(d1[j] > dist + w[i])
            {
                d1[j] = dist + w[i];
                num[j] = num[ver];
                sum[j] = sum[ver] + re[j];
                pre[j] = ver;
                q.push({d1[j], j});
            }
            else if(d1[j] == dist + w[i])
            {
                num[j] += num[ver];
                if(sum[j] < sum[ver] + re[j])
                {
                    sum[j] = sum[ver] + re[j];
                    pre[j] = ver;
                }
                q.push({d1[j], j});
            }
        }
    }
}
void Path()
{
    int k = 0;
    int x = t;
    while(x != s)
    {
        a[k ++ ] = x;
        x = pre[x];
    }
    reverse(a, a + k);
    cout << '0' << ' ';
    for(int i = 0; i < k; i ++ )
    {
        if(i != k - 1)
        cout << a[i] << ' ';
        else cout << a[i] << endl;
    }
}
int main()
{
    memset(h, -1, sizeof h);
	cin >> n >> m >> s >> t;
	for(int i = 0; i < n; i ++ ) cin >> re[i];
	for(int i = 0; i < m; i ++ )
	{
	    int a, b, c;
	    cin >> a >> b >> c;
	    add(a, b, c);
	    add(b, a, c);
	}
	memset(vis, 0, sizeof vis);
	memset(pre, -1, sizeof pre);
	num[s] = 1;
	sum[s] = re[s];
	dijkstra();
	
	cout << num[t] << ' ' << sum[t] << endl;
	Path();
	return 0;
}

相關文章