PAT 1003. Emergency

来源:互联网 发布:理发软件 编辑:程序博客网 时间:2024/05/16 10:33

【题目链接】

一开始看错了题目,以为第一个输出是要求最短距离,后来才发现是要求最短路径的条数。对于最短路径的条数和点权之和我们可以分别用两个数组numberPath[]和numberTeam[]来实现,numberPath[i]记录从起点到顶点i的最短路径的条数,numberTeam[i]记录从从起点到顶点i的所有最短路径中点权之和的最大值。然后当加入新的顶点之后得到的距离等于原来的最短距离,则对numberPath进行累加,此时如果新的最短路径上的点权之和最大,则更新numberTeam。

若加入新的顶点之后距离更小了,则更新最短距离,重置最短路径条数为起点到加入的点之间的最短路径条数,并重新计算新的最短路径上的点权之和。

提交代码:

<span style="font-size:18px;">#include <iostream>#include <algorithm>using namespace std;const int MAXV = 510;const int INF = 10000000;int n, m, G[MAXV][MAXV];int d[MAXV]; //记录起点到各点的最短路径长度bool vis[MAXV] = {false};int team[MAXV]; //记录每个城市的team数量,即点权int currentV, saveV; //起点和终点int numberPath[MAXV]; //记录起点到各点的最短路径的条数int numberTeam[MAXV]; //记录起点到各点最短路径上经过的所有点的权值之和void Dijkstra(){    d[currentV] = 0; //起点到自身的距离为0    numberTeam[currentV] = team[currentV]; //到起点的总权值之和初始化为起点的点权    for(int i = 0; i < n; i++) //选到起点距离最小的点    {        int u = -1, MIN = INF;        for(int j = 0; j < n; j++)            if(!vis[j] && d[j] < MIN)                MIN = d[u = j];        if(u == -1) return ; //如果所有的点都加入集合了,则返回        vis[u] = true;        for(int v = 0; v < n; v++)            if(!vis[v])            {                if(d[u] + G[u][v] == d[v])                {                    numberPath[v] += numberPath[u]; //累加最短路径的条数                    if(numberTeam[u] + team[v] >  numberTeam[v]) //找到更大的,则更新总的点权                        numberTeam[v] = numberTeam[u] + team[v];                }                else if(d[u] + G[u][v] < d[v])                {                    numberPath[v] = numberPath[u];                    d[v] = d[u] + G[u][v]; //更新最短距离                    numberTeam[v] = numberTeam[u] + team[v]; //计算最短路径上的点权之和                }            }    }}int main(){    //freopen("in.txt", "r", stdin);    cin >> n >> m >> currentV >> saveV; //输入城市的个数、路的条数、当前所在地和目的地    for(int i = 0; i < n; i++)        cin >> team[i];    for(int i = 0; i < n; i++) //初始化邻接矩阵G        for(int j = 0; j < n; j++)            G[i][j] = INF;    fill(d, d + MAXV, INF); //初始化距离为无穷大    fill(numberPath, numberPath + MAXV, 1); //初始化 起点到各点的路径条数为1    int start, end, distance;    for(int i = 0; i < m; i++)    {        cin >> start >> end >> distance;        G[start][end] = G[end][start] = distance;    }    Dijkstra();    cout << numberPath[saveV] << " " << numberTeam[saveV];}</span>


0 0
原创粉丝点击