题目连接

https://www.acwing.com/problem/content/description/4249/

http://poj.org/problem?id=1511

思路

其实这道题和农场派对这题是一样的,我们反向建边就能求出所有其他点到1这个点的距离,然后直接加上去就好了,但是不同的是这题的数据非常大,所以如果你是使用vector或者其他容器存储的话是会MLE的,所以我们这里手写链式前向星然后每次跑DJ的时候注意初始化就好了,下面放出两种写法的代码(第二种是MLE的)

代码

链式前向星+堆优化Djakarta

#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
#define INF 0x3f3f3f3f
const int N=2e6+5;//数据范围
struct edge{//存储边int u,v,w,next;//u为起点,v为终点,w为权值,next为前继
};
edge e[N];
int head[N],dis[N],n,m,s,cnt;//head为链中最上面的,dis表示当前答案,n为点数,m为边数,s为起点,cnt记录当前边的数量
bool vis[N];//vis表示这个点有没有走过
struct node{int w,to;//w表示累加的权值,to表示到的地方bool operator <(const node &x)const{//重载“<”号return w>x.w;}
};void add(int u,int v,int w){++cnt;//增加边的数量e[cnt].u=u;//存起点e[cnt].v=v;//存终点e[cnt].w=w;//存权值e[cnt].next=head[u];//存前继head[u]=cnt;//更新链最上面的序号
}//链式前向星(加边)
void Dijkstra(){dis[s]=0;//起点到自己距离为0priority_queue<node>q;//优先队列(堆优化)q.push(node{0,s});//压入队列while(!q.empty()){//队列不为空node x=q.top();//取出队列第一个元素q.pop();//弹出int u=x.to;//求出起点if(vis[u]) continue;//已去过就不去了vis[u]=true;//标记已去过for(int i=head[u];i;i=e[i].next){int v=e[i].v;//枚举终点if(dis[v]>dis[u]+e[i].w){//若中转后更优,就转dis[v]=dis[u]+e[i].w;//更新q.push(node{dis[v],v});//压入队列}}}
}
int U[N],V[N],W[N];void init(){int l = max(n,m);for(int i = 1;i <= l; ++i) {head[i] = 0,vis[i] = false;dis[i] = INF;}cnt = 0;
}int main(){int u,v,w = 1;s = 1;int t;scanf("%d",&t);while(t--){scanf("%d%d",&n,&m);//输入init();for(int i = 1;i <= m;++i){scanf("%d%d%d",&U[i],&V[i],&W[i]);add(U[i],V[i],W[i]);}Dijkstra();//DJlong long ans = 0;for(int i = 2;i <= n; ++i)ans += dis[i];init();for(int i = 1;i <= m;++i){add(V[i],U[i],W[i]);}Dijkstra();for(int i = 2;i <= n; ++i)ans += dis[i];printf("%lld\n",ans);}return 0;
}

使用容器存储

#include<cstdio>
#include<cstring>
#include<queue>
#include<iostream>
using namespace std;
#define PII pair<int,int>
#define INF 0x3f3f3f3f
const int N = 1e6+10;
int dis[N],n,x,m;
struct Node{int v,w;
};
vector<Node> E[N];
bool vis[N];void DJ(int s){priority_queue<PII,vector<PII>,greater<PII> > que;que.push({0,s});dis[s] = 0;while(!que.empty()){int t = que.top().second;que.pop();if(vis[t]) continue;vis[t] = true;for(int i  = 0, l = E[t].size();i < l; ++i) {int j = E[t][i].v;int w = E[t][i].w;if(dis[j] > dis[t] + w){dis[j] = dis[t] + w;que.push({dis[j],j});}}}
}void init(){for(int i = 1;i <= n; ++i) vis[i] = false,dis[i] = INF;for(int i = 1;i <= n; ++i) E[i].clear();
}int U[N],V[N],W[N];
int main()
{ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);int t;cin>>t;while(t--){cin>>n>>m;int u,v,w;init();for(int i = 1;i <= m; ++i){cin>>U[i]>>V[i]>>W[i];E[U[i]].push_back({V[i],W[i]});//正向建图E[v].push_back({u,w});//反向建图}long long ans = 0;DJ(1);for(int i = 1;i <= n; ++i)ans += dis[i];init();for(int i = 1;i <= m; ++i)E[V[i]].push_back({U[i],W[i]});//反向建图DJ(1);for(int i = 1;i <= n; ++i)ans += dis[i];cout<<ans<<endl;}return 0;
}

AcWing 4246. 最短路径和(反向建图+链式前向星+堆优化)相关推荐

  1. HDU1535 Invitation Cards(链式前向星+堆优化dijkstra)[C++]

    目录 题目及翻译 题面 输入 输出 输入样例 输出样例 题目思路 注意事项 AC代码 C++ 题目及翻译 题面 In the age of television, not many people at ...

  2. 迪杰斯特拉最全详解(朴素版,堆优化+邻接表存图/链式前向星存图)

    迪杰斯特拉 迪杰斯特拉算法分析 迪杰斯特拉(朴素版) 迪杰斯特拉堆优化(邻接表存图) 迪杰斯特拉堆优化(链式前向星存图) 最短路--spfa(链式前向星存图) 迪杰斯特拉算法分析 一般用三种数据结构存 ...

  3. 前向星和链式前向星(详解+模板)

    前向星和链式前向星 参考博客:深度理解链式前向星 什么是前向星 前向星是一种特殊的边集数组,我们把边集数组中的每一条边按照起点从小到大排序,如果起点相同就按照终点从小到大排序,并记录下以某个点为起点的 ...

  4. 数据结构【链式前向星】

    第一次接触链式前向星是在学习图论的迪杰斯特拉算法时,大佬们纷纷用链式前向星+堆优化+迪杰斯特拉解题,秀的我萌新懵的一批,当时不知道啥是链式前向星,不过随着越来越深入,这种结构见得越来越多,慢慢的就明白 ...

  5. 蓝桥集训之BFS、DFS和链式前向星

    配套视频 https://www.bilibili.com/video/BV1RD4y1F7Fq 一.建图基础 前言 图一般定义为二元集: 由顶点集与边集构成. 或者更抽象的说,由一个集合(顶点),和 ...

  6. 链式前向星模板 建图+dfs+bfs+dijkstra

    边没有用struct封装起来,节点和边的计数起点如果不符合习惯可以稍作修改 建图+DFS+BFS #include <cstdio> #include <cstring> #i ...

  7. Djisktra + 链式前向星建图 + PriorityQueue堆优化【附Java代码模板题解】

    Djisktra堆优化(链式前向星)

  8. 图的储存方式,链式前向星最简单实现方式 (边集数组)

    对于图来说,储存方式无非就是邻接矩阵.邻接表,今天看了看链式前向星的储存方式,说来说去不还是链表,是一种链表的简单的实现方式,还是比较好理解的.看他们写个结构体,个人不喜欢,没必要,也嫌麻烦,换一种更 ...

  9. 图的存储 邻接矩阵+邻接表+链式前向星

    图的存储 - 邻接矩阵 在树的问题中,邻接矩阵是空间.时间的极大浪费. 假设树的结点个数为 N = 100000. 建立邻接矩阵需要空间为 1e5*1e5 但是由于只有 N - 1 条边,所以在邻接矩 ...

最新文章

  1. nanopore测序技术专题(六):测序错误率太高无法使用?
  2. 彻底颠覆神经科学?神经信号可能不是电信号,而是机械波?!
  3. 如何将UI5应用部署到Fiori On-Premise和On-Cloud的Launchpad上去
  4. 在导入graphsurgeon时报错:ImportError: cannot import name ‘NodeDef‘ from ‘tensorflow‘
  5. 建立索引要考虑的因素
  6. 剑指Offer面试题:2.二维数组中的查找
  7. appium+python+iOS 环境搭建与使用中常见问题的解决方案链接
  8. linux终端自动输入,linux shell自动输入实现
  9. go语言实现zip压缩与解压
  10. oracle中时间、日期函数的总结
  11. [转载] comma.ai自动驾驶代码浅析及实践
  12. linux cut 命令详解
  13. 7-14 到底是不是太胖了 (10 分)
  14. shader 如何声明数组_聊聊如何正确向Compute Shader传递数组
  15. Python文本处理(3)——文本表示之 one-hot 词向量(1)——纯小白都能懂!
  16. 基于C/C++的PCM编码与解码简单实现
  17. 读书笔记:《产品经理修炼之道》读后感
  18. dev-c++输出的中文乱码
  19. 第十四届蓝桥杯模拟赛第一期试题【Java解析】
  20. 函数定义涉及的三要素C语言,(函数定义与三要素答案.doc

热门文章

  1. Linux时间设置和motd设置
  2. MDS(多维尺度变换)降维算法
  3. python大数据工程师薪资待遇_2019年就业薪资,凭什么大数据工程师遥遥领先?...
  4. MySQL~索引设计原则:适合创建索引的11种情况、不适合创建索引的7种情况
  5. Intellij IDEA集成sencha插件开发Extjs应用
  6. cassandra多个数据中心实现异地容灾
  7. 基于友盟+U-APM解决客户小姐姐Android Native Crash问题,小姐姐说我真棒,要把她闺蜜介绍给我
  8. 判断是否多喝一瓶酸奶
  9. 数据库发展竟然和阿波罗登月有关?还有什么是我们不知道的?
  10. java espresso_java-Espresso-如何检查是否显示了其中一个视图