ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

G - Reducing Delivery Cost -最短路

2022-03-07 14:02:51  阅读:157  来源: 互联网

标签:int 短路 inq Delivery vis Cost push Reducing dis


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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有