- 终于考完试了,追赶一下葛葛的进度,今天复习一下最小生成树的内容,说是最小生成树,但其实蛮多最短路径的问题的,所以就一块练习一下。
P1339 [USACO09OCT]Heat Wave G - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
题解:
- 模板题了,算是迪杰斯特拉的,我直接上版子,虽然很多时候我也想多对一个算法思考一会,可最近真的是在赶进度吧,算是,所以重复的代码我不想敲,所以我直接上模板
代码如下:
#include
#include
#include
P1396 营救 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
代码如下:(正好水一下快读模板)
#include
#include
#include
P1342 请柬 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
题意:
输出最小费用=输出最小生成树(这么做之后人傻了)原来是要用Dijstral+堆优化来做呀,呜呜呜!(SPFA也可以当然),正好可以介绍一下这个优化的算法。
- 堆优化利用到了优先队列,而这个题的话需要用最短路径算法计算两遍,然后统计即可。
借鉴大佬们的代码->
#include
#include
#include
#include
#include
#define INF 0x3f3f3f3f
using namespace std;
const int N = 3000000;
int n, m;
int h1[N], h2[N];
int s1, s2;
struct node {
int next;
int to;
int dis;
}e1[N], e2[N];
int vis1[N], vis2[N];
long long dis1[N], dis2[N];
void add1(int x, int y, long long w)
{
e1[++s1].dis = w;
e1[s1].next = h1[x];
e1[s1].to = y;
h1[x] = s1;
}
void add2(int x, int y, long long w)
{
e2[++s2].dis = w;
e2[s2].next = h2[x];
e2[s2].to = y;
h2[x] = s2;
}
void dij1(int start)
{
priority_queue > q;
memset(dis1, INF, sizeof(dis1));
memset(vis1, 0, sizeof(vis1));
q.push(make_pair(0, start));
dis1[1] = 0;
while (!q.empty())
{
long long k;
int t = q.top().second;
q.pop();
if (vis1[t]) {
continue;
}
vis1[t] = 1;
for (int i = h1[t]; i; i = e1[i].next)
{
int j = e1[i].to;
k = e1[i].dis;
if (dis1[t] + k < dis1[j])
{
dis1[j] = dis1[t] + k;
q.push(make_pair(-dis1[j], j));//距离最小的先弹出,也可以直接运算符重载
}
}
}
}
void dij2(int start)
{
memset(dis2, INF, sizeof(dis2));
memset(vis2, 0, sizeof(vis2));
priority_queue > q;
q.push(make_pair(0, start));
dis2[1] = 0;
while (!q.empty())
{
long long k;
int t = q.top().second;
q.pop();
if (vis2[t]) {//队首的这个点是否已经被扫描过
continue;
}
vis2[t] = 1;
for (int i = h2[t]; i; i = e2[i].next)
{
int j = e2[i].to;
k = e2[i].dis;
if (dis2[t] + k < dis2[j])
{
dis2[j] = dis2[t] + k;
q.push(make_pair(-dis2[j], j));
}
}
}
}
int main()
{
cin >> n >> m;
long long x, y, z;
for (int i = 1; i <= m; i++)
{
cin >> x >> y >> z;
add1(x, y, z);
add2(y, x, z);
}
long long ans = 0;
dij1(1);
dij2(1);
for (int i = 1; i <= n; i++)
{
ans += dis1[i] + dis2[i];
}
cout << ans << endl;
}