題解 CF1433G 【Reducing Delivery Cost】
阿新 • • 發佈:2020-10-23
Solution CF1433G Reducing Delivery Cost
題目大意:給定一張 \(n\) 個點 \(m\) 條邊的帶權無向圖,記 \(d(u,v)\) 為 \(u\) 到 \(v\) 的最短路,給定 \(k\) 個點對 \((a_i,b_i)\)。你可以使任意一條邊的邊權變為 \(0\),求\(\sum_{i=1}^kd(a_i,b_i)\) 的最小值
最短路
分析:
我們先預處理出原圖兩兩之間的最短路
將任意一邊的權值置為 \(0\) 之後,最短路徑可以分為兩類:經過 \(0\) 邊的,和不經過 \(0\) 邊的
不經過的 \(0\) 邊的我們已經預處理出來了
假設 \(0\)
由於是無向圖,要考慮 \((a,b)\) 和 \((b,a)\) 兩種情況,然後依次列舉每條邊求解即可
#include <cstdio> #include <cctype> #include <cstring> #include <algorithm> #include <vector> #include <set> #include <queue> #include <utility> using namespace std; const int maxn = 1024; inline int read(){ int x = 0;char c = getchar(); while(!isdigit(c))c = getchar(); while(isdigit(c))x = x * 10 + c - '0',c = getchar(); return x; } struct edge{ int u,v,d; bool operator == (const edge &rhs)const{ if((u == rhs.u) && (v == rhs.v))return true; if((v == rhs.u) && (u == rhs.v))return true; return false; } }; vector<edge> G[maxn],edges; vector<pair<int,int>> vec; inline void addedge(int u,int v,int d){ G[u].push_back(edge{u,v,d});G[v].push_back(edge{v,u,d}); if(u > v)swap(u,v); edges.push_back(edge{u,v,d}); } int dis[maxn][maxn],vis[maxn]; struct node{ int u,h; inline bool operator < (const node &rhs)const{ return h > rhs.h; } }; inline void dijkstra(int s){ memset(dis[s],0x3f,sizeof(dis[s])); memset(vis,0,sizeof(vis)); priority_queue<node> q; dis[s][s] = 0; q.push(node{s,0}); while(!q.empty()){ int u = q.top().u;q.pop(); if(vis[u])continue; vis[u] = 1; for(auto e : G[u]){ if(dis[s][u] + e.d < dis[s][e.v]){ dis[s][e.v] = dis[s][u] + e.d; q.push(node{e.v,dis[s][e.v]}); } } } } int n,m,k,ans = 0x7fffffff; int main(){ n = read(),m = read(),k = read(); for(int u,v,d,i = 1;i <= m;i++) u = read(),v = read(),d = read(),addedge(u,v,d); for(int u,v,i = 1;i <= k;i++){ u = read(),v = read(); vec.push_back(make_pair(u,v)); } for(int i = 1;i <= n;i++)dijkstra(i); for(auto e : edges){ int tmp = 0; for(auto p : vec){ int u = p.first,v = p.second; tmp += min(dis[u][v],min(dis[u][e.u] + dis[v][e.v],dis[u][e.v] + dis[v][e.u])); } ans = min(ans,tmp); } printf("%d\n",ans); return 0; }