题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3946
题意:Marjar帝国的皇帝爱德华想要建造一些双向高速公路,以便尽可能快地从首都到达其他城市。 因此,他提出了高速公路项目。Marjar帝国有N个城市(包括首都),从0到N - 1(首都是0)的索引,并且可以建造M条高速公路。 建设第i高速公路需要Ci美元。 在i-th高速公路上,Xi到Yi需要Di分钟。
爱德华希望找到一个建筑计划,从首都到达其他城市所需的总时间最短,即从首都到城市i所需的最短时间总和(1≤i≤N)。 在所有可行的计划中,爱德华想要以最低的成本选择计划。 请帮助他完成这项任务。
思路:这题是在路径最短的境况下选择最少的花费,所以需要在松弛的时候对花费进行更新操作,假如说三个点被线连着,第一个点也连着第三个点,因为dij对边进行松弛的时候,总是选择在dis数组里面离源点最近的而且没松弛过的,所以从最短路径来说,这个点肯定是最短路径里的点了,但是如果加了花费这个条件的话,所以当我们判断如果dis[1-3]==dis[1-2-3]的话,我们还要判断它们的花费需不需要更新。注意更新的时候花费不要累加,因为路只要修一遍。
#include
using namespace std;
#define pii pair
#define ll long long
const int N = 1e5+7;
vector E[N], Ep[N];
int vis[N], n, m;
ll d[N], p[N];
void init()
{memset(d, 0x3f, sizeof(d));memset(vis, 0, sizeof(vis));for(int i = 0; i }
void Dijkstra()
{priority_queue Q;Q.push({-d[0], 0});while(!Q.empty()){int now = Q.top().second;Q.pop();if(vis[now]) continue;vis[now] = 1;for(int i = 0; i d[now] + E[now][i].second){d[v] = d[now] + E[now][i].second;p[v] = Ep[now][i].second;Q.push({-d[v], v});}else if(d[v] == d[now] + E[now][i].second && p[v] > Ep[now][i].second)p[v] = Ep[now][i].second;}}
}
int main()
{int t;scanf("%d", &t);while(t--){init();scanf("%d%d", &n, &m);for(int i = 0; i }