G - Reducing Delivery Cost -最短路
作者:互联网
G - Reducing Delivery Cost
题意:
给你n个点和m条边以及每条边的权值 允许让一条边的权值变成0 然后有q次询问 求q次询问的xi到yi的最小路径和
思路:
显然是最短路的题 但是直接套最短路模板 枚举每条免费的边然后再dij每个点 来求 时间复杂度 是 n* m * k * log(m)会超时
所以就要考虑 先预处理每两个点的最短路 用dis[x][y]储存 后续再枚举每条边 求最短路
对于一条免费的边有两种情况
- 免费前后都不在最短路径中 那么就是没有影响
- 免费后在最短路径中 最短路那么就要取免费后更小的值(比较dis[i][j] , dis[i][x] + dis[y][j], dis[i][y] + dis[x][j] 取较小值)
#include <bits/stdc++.h> #include <queue> #define ll unsigned long long #define pi acos(-1) #define FF ios::sync_with_stdio(false), cin.tie(0) using namespace std; const int mod = 1e9 + 7; const int N = 1e6 + 10; const int inf = 0x3f3f3f3f; int n, m, qq, dis[1010][1010]; struct node{ int to, w; }; vector<node> g[N]; vector<pair<int, int> >v; int vis[1010], inq[1010]; priority_queue<pair<int ,int>, vector<pair<int ,int> >, greater<pair<int ,int> > >q; //最短路算法 void dij(int x){ //初始化 memset(vis, 0, sizeof(vis)); memset(inq, 0, sizeof(inq)); dis[x][x] = 0;//自己到自己值为零 q.push(make_pair(dis[x][x], x)); inq[x] = 1;//记录已在队列中 while(!q.empty()){ pair<int, int>now = q.top(); q.pop(); if(vis[now.second]) continue; vis[now.second] = 1;//判断是否已经访问过 int from = now.second; for(int i = 0; i < g[from].size(); i++){ int to = g[from][i].to; int w = g[from][i].w;//注意写法 不要用min函数 if(dis[x][to] > dis[x][from] + w){ dis[x][to] = dis[x][from] + w; if(!inq[to]) q.push(make_pair(dis[x][to], to)); } } } } int main() { FF; cin >> n >> m >> qq; for(int i = 1; i <= m; i++){ int x, y, w; cin >> x >> y >> w; g[x].push_back({y, w}); g[y].push_back({x, w}); } memset(dis, inf, sizeof(dis));//因为是取最小 所以一开始要很大 for(int i = 1; i <= n; i++){//预处理最短路 dij(i); } for(int i = 1; i <= qq; i++){ int a, b; cin >> a >> b; v.push_back(make_pair(a, b)); } int anss = inf; for(int i = 1; i <= n; i++){ for(int j = 0; j < g[i].size(); j ++){ int t = g[i][j].to; int ans = 0; for(int k = 0; k < v.size(); k++){ int from = v[k].first, to = v[k].second; //直接用ans+= 不要更新dis 不然会出错 比大小的时候不要忘了是三个值比较 容易把dis[from][t]+dis[i][to]忘记 ans += min({dis[from][to], dis[from][i] + dis[t][to], dis[from][t] + dis[i][to]}); } anss = min(anss, ans);//对于每条免费边答案取最小 } } cout << anss << "\n"; return 0; }
标签:int,短路,inq,Delivery,vis,Cost,push,Reducing,dis 来源: https://www.cnblogs.com/yaqu-qxyq/p/15975596.html