P1629 邮递员送信
题意:求从1到[2, n]中每一个点的最短路\(k_i\),再求从[2, n]的每一个点出发到1的最短路\(p_i\), 求所有\(k, p\)的和。
堆优化dijkstra \(O(nmlogn)\):40pts
#include<iostream>
#include<cstring>
#include<queue>
#include<vector>
using namespace std;
const int N = 1010, M = 100010, INF = 0x3f3f3f3f;
int h[N], e[M], ne[M], w[M], idx;
int dist[N], st[N];
int n, m, q;
struct Node{
int val, idx;
bool operator > (const Node &n) const {
return val > n.val;
}
};
priority_queue<Node, vector<Node>, greater<Node>> heap;//小根堆
int dijkstra(int x, int y){
memset(dist, 0x3f, sizeof dist);
memset(st, 0, sizeof st);
dist[x] = 0;
heap.push({0, x});
while(heap.size()){
int k = heap.top().idx;
heap.pop();
if(st[k]) continue;
st[k] = 1;
for(int i = h[k]; ~i; i = ne[i]){
int j = e[i];
if(dist[j] > dist[k] + w[i]){
dist[j] = dist[k] + w[i];
heap.push({dist[j], j});
}
}
}
return dist[y];
}
void add(int a, int b, int v){
e[idx] = b, w[idx] = v, ne[idx] = h[a], h[a] = idx ++;
}
int main(){
memset(h, -1, sizeof h);
cin >> n >> m;
while(m --){
int a, b, v;
cin >> a >> b >> v;
add(a, b, v);
}
int res = 0;
for(int i = 2; i <= n; i ++)
res += dijkstra(1, i) + dijkstra(i, 1);
cout << res;
return 0;
}
建反向图+堆优化dijkstra \(O(mlogn)\)
#include<iostream>
#include<cstring>
#include<queue>
#include<vector>
using namespace std;
const int N = 1010, M = 100010, INF = 0x3f3f3f3f;
int h[N << 1], e[M << 1], ne[M << 1], w[M << 1], idx;
int dist[N << 1], st[N << 1];
int n, m, q;
struct Node{
int val, idx;
bool operator > (const Node &n) const {
return val > n.val;
}
};
priority_queue<Node, vector<Node>, greater<Node>> heap;
void dijkstra(int x){
dist[x] = 0;
heap.push({0, x});
while(heap.size()){
int k = heap.top().idx;
heap.pop();
if(st[k]) continue;
st[k] = 1;
for(int i = h[k]; ~i; i = ne[i]){
int j = e[i];
if(dist[j] > dist[k] + w[i]){
dist[j] = dist[k] + w[i];
heap.push({dist[j], j});
}
}
}
}
void add(int a, int b, int v){
e[idx] = b, w[idx] = v, ne[idx] = h[a], h[a] = idx ++;
}
int main(){
memset(dist, 0x3f, sizeof dist);
memset(h, -1, sizeof h);
memset(st, 0, sizeof st);
cin >> n >> m;
while(m --){
int a, b, v;
cin >> a >> b >> v;
add(a, b, v);
add(b + n, a + n, v);
}
int res = 0;
dijkstra(1);// 1~n原图
dijkstra(1 + n); // n + 1到2n反向图
for(int i = 1; i <= n << 1; i ++) res += dist[i];
cout << res;
return 0;
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步