1003 Emergency --dijkstra

team数组保存当前经过路径招的人数,除了出发点初始全为0.
pn数组保存最短路径数,初始为0,出发点为1.
最短路松弛时,dist更小时,更新team, pn赋新值;
dist相等时, pn加上前驱点的pn值,如果team更多,更新team

#include 
#include 
#include 
#include 
using namespace std;

const int INF = 0x3f3f3f3f;
const int MAXN = 510;
int dist[MAXN], team[MAXN], pn[MAXN];
int num[MAXN];
vectorint, int> > mp[MAXN];

void dij(int n, int begin, int end) {
    memset(dist, 0x3f, sizeof(dist));
    dist[begin] = 0;

    memset(team, 0, sizeof(team));
    team[begin] = num[begin];

    memset(pn, 0, sizeof(pn));
    pn[begin] = 1;

    bool book[MAXN];
    memset(book, false, sizeof(book));

    for (int k = 0; k < n; k++) {
        int u = n;
        for (int j = 0; j < n; j++)
            if (!book[j] && dist[u] > dist[j])
                u = j;

        if (u == end)
            return;
        book[u] = true;

        for (vectorint, int> >::iterator it = mp[u].begin(); it != mp[u].end(); it++) {
            if (book[it->first])
                continue;

            if (dist[it->first] > dist[u] + it->second) {
                dist[it->first] = dist[u] + it->second;
                team[it->first] = team[u] + num[it->first];
                pn[it->first] = pn[u];
            } else if (dist[it->first] == dist[u]+it->second) {
                if (team[it->first] < team[u] + num[it->first])
                    team[it->first] = team[u] + num[it->first];
                pn[it->first] += pn[u];
            }
        }
    }
}

int main() {
    int n, m, begin, end;
    while (~scanf("%d%d%d%d", &n, &m, &begin, &end)) {
        for (int i = 0; i < n; i++)
            scanf("%d", &num[i]);
        while (m--) {
            int x, y, d;
            scanf("%d%d%d", &x, &y, &d);
            mp[x].push_back(make_pair(y, d)); 
            mp[y].push_back(make_pair(x, d));
        }
        dij(n, begin, end);
        printf("%d %d\n", pn[end], team[end]);
        for (int i = 0; i < n; i++)
            mp[i].clear();
    }
    return 0;
}

你可能感兴趣的:(1003 Emergency --dijkstra)