题解 CF1433G 【Reducing Delivery Cost】

题目链接

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;
}
原文地址:https://www.cnblogs.com/colazcy/p/13864977.html