本题的题意:给定 n 个城市和 m 条连接城市的道路,每座城市都有相应的权值。计算从 c1 城市到 c2 城市最短路的条数 t,并在最短路的情况下,并计算 t 座城市路径权值的最大值。
解题思路:本题采用 Dijkstra 算法,进行相应的改变,即可完成题目解答。其中,部分细节已在代码中有所注释。
题目链接:https://www.patest.cn/contests/pat-a-practise/1003
#include <iostream> #include <algorithm> #include <map> #include <stack> #include <queue> #include <vector> #include <set> using namespace std; const int CITY_NUM = 505; const int INF = 1<<30; typedef struct CityInfo//City的信息 { int numPath,teams,sum,lowcost; bool visited; }CityInfo; CityInfo CC[CITY_NUM]; int GMap[CITY_NUM][CITY_NUM];//邻接矩阵 void init()//一些初始化 { for(int i=0;i<CITY_NUM;++i) { CC[i].visited = false; CC[i].sum = 0; CC[i].numPath = 0; CC[i].lowcost = INF; for(int j=0;j<CITY_NUM;++j) GMap[i][j] = INF; } } void dijk(int c1,int n) { //对起始点做一些单独的设定 int u = c1; CC[u].sum = CC[u].teams; CC[u].numPath = 1; CC[u].lowcost = 0; for(int i=0;i<n;++i) { CC[u].visited = true; //更新点周围相邻点的信息 for(int j=0;j<n;++j) { if(CC[u].lowcost + GMap[u][j] < CC[j].lowcost && CC[j].visited == false) { CC[j].lowcost = CC[u].lowcost + GMap[u][j]; CC[j].sum = CC[u].sum + CC[j].teams; CC[j].numPath = CC[u].numPath;//注意点:路径条数是继承上一点的条数的,而不是 1 } else if(CC[u].lowcost + GMap[u][j] == CC[j].lowcost && CC[j].visited == false) { CC[j].numPath += CC[u].numPath;//同样的注意点,而不是自增这么简单 if(CC[u].sum + CC[j].teams > CC[j].sum) { CC[j].sum = CC[u].sum + CC[j].teams;//计算出权值最大 } } } int min = INF,pos; for(int j=0;j<n;++j)//找下一个节点 { if(min > CC[j].lowcost && CC[j].visited == false) { min = CC[j].lowcost; pos = j; } } u = pos; } } int main(int argc, char** argv) { int n,m,c1,c2; cin >> n >> m >> c1 >> c2; init(); for(int i=0;i<n;++i) { cin >> CC[i].teams; } for(int i=0;i<m;++i) { int x1,x2,dis; cin >> x1 >> x2 >> dis; GMap[x1][x2] = dis; GMap[x2][x1] = dis; } dijk(c1,n); cout << CC[c2].numPath << " " << CC[c2].sum << endl; return 0; }
