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)),我们要求的是 (d(u,v)),那么(d(u,v)=d(u,a)+ d(b,v))
由于是无向图,要考虑 ((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
",ans);
return 0;
}