JZYZOJ1525 HAOI2012道路 堆优化的dijkstra+pair

From Tyvj Guest

[haoi2012]道路

 
     
     
  描述 Description  
  C国有n座城市,城市之间通过m条单向道路连接。一条路径被称为最短路,当且仅当不存在从它的起点到终点的另外一条路径总长度比它小。两条最短路不同,当且仅当它们包含的道路序列不同。我们需要对每条道路的重要性进行评估,评估方式为计算有多少条不同的最短路经过该道路。现在,这个任务交给了你。
     
     
  输入格式 Input Format  
  第一行包含两个正整数n、m
接下来m行每行包含三个正整数u、v、w,表示有一条从u到v长度为w的道路
     
     
  输出格式 Output Format  
  输出应有m行,第i行包含一个数,代表经过第i条道路的最短路的数目对1000000007取模后的结果
     
     
     
 

样例输入

4 4

1 2 5

2 3 5

3 4 5

1 4 8

样例输出

2

3

2

1

最后的代码

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<queue>
  6 using namespace std;
  7 #define pa pair<int,int>
  8 const int mymod=1000000007;
  9 const int bign=1000000000;
 10 int n,m;
 11 struct wtff{
 12     int y;
 13     int next;
 14     int zhi;
 15 }wtf[5010];
 16 int head[1510]={};
 17 int tail=0;
 18 long long ans[5010]={};
 19 long long a[5010]={};
 20 long long b[5010]={};
 21 int c[1510]={};
 22 long long dis[1510]={};
 23 bool vis[1510]={};
 24 void init(int x,int y,int zhi){
 25     wtf[++tail].next=head[x];
 26     wtf[tail].zhi=zhi;
 27     wtf[tail].y=y;
 28     head[x]=tail;
 29 }
 30 void jiuming(int st){
 31     priority_queue< pa,vector<pa>,greater<pa> >q;
 32     memset(vis,0,sizeof(vis));
 33     for(int i=1;i<=n;i++){
 34         dis[i]=bign;
 35     }
 36     dis[st]=0;
 37     q.push(make_pair(0,st));
 38     int cn=0;
 39     while(!q.empty()){
 40         int x=q.top().second;
 41         q.pop();
 42         if(vis[x]){
 43             continue;
 44         }
 45         vis[x]=1;
 46         c[++cn]=x;
 47         for(int i=head[x];i!=0;i=wtf[i].next){
 48             int y;
 49             y=wtf[i].y;
 50             if(dis[x]+wtf[i].zhi<dis[y]){
 51                 dis[y]=dis[x]+wtf[i].zhi;
 52                 q.push(make_pair(dis[y],y));
 53             }
 54         }
 55     }
 56     memset(a,0,sizeof(a));
 57     memset(b,0,sizeof(b));
 58     a[st]=1;
 59     for(int i=1;i<=cn;i++){
 60         b[c[i]]=1;
 61     }
 62     for(int i=1;i<=cn;i++){
 63         for(int w=head[c[i]];w!=0;w=wtf[w].next){
 64             int y=wtf[w].y;
 65             if(dis[c[i]]+wtf[w].zhi==dis[y]){
 66                 a[y]+=a[c[i]];
 67                 if(a[y]>mymod){
 68                     a[y]%=mymod;
 69                 }
 70             }
 71         }
 72     }
 73     for(int i=cn;i>=1;i--){
 74         for(int w=head[c[i]];w!=0;w=wtf[w].next){
 75             int y=wtf[w].y;
 76             if(dis[c[i]]+wtf[w].zhi==dis[y]){
 77                 b[c[i]]+=b[y];
 78                 if(b[c[i]]>mymod){
 79                     b[c[i]]%=mymod;
 80                 }
 81             }
 82         }
 83     }
 84     for(int i=1;i<=n;i++){
 85         for(int w=head[i];w!=0;w=wtf[w].next){
 86             int y=wtf[w].y;
 87             if(dis[i]+wtf[w].zhi==dis[y]){
 88                 ans[w]+=(a[i]*b[y]);
 89                 if(ans[w]>mymod){
 90                     ans[w]%=mymod;
 91                 }
 92             }
 93         }
 94     }
 95 }
 96 int main(){
 97     cin>>n>>m;
 98     for(int i=1;i<=m;i++){
 99         int a1,b1,c1;
100         cin>>a1>>b1>>c1;
101         init(a1,b1,c1);
102     }
103     for(int i=1;i<=n;i++){
104         jiuming(i);
105     }
106     for(int i=1;i<=m;i++){
107         cout<<ans[i]<<endl;
108     }
109     return 0;
110 }

http://www.cnblogs.com/zyfzyf/p/3995257.html

完全没有进展,迪杰斯特拉部分的堆之类的大部分看不懂,加油啃。。。

几乎是抄着代码过的,还要自己再写一遍.....

大概算是理解时候的备注

c指代经过其他点得到最短路的点

dijkstra算法可以在算出最短路的同时将点的源点的距离排序,然后按照这个

从前往后枚举在最短路上的边可以得到源点到每个点的最短路的数目,记为a[i]

从后往前枚举在最短路上的边可以得到经过每个点有多少条最短路,记为b[i]

然后对于每条边就是 +=a[e[i].from]*b[e[i].go]

↑大神的方法...

用小根堆写迪杰斯特拉来记录c...我觉得我永远想不出来这么神奇的方法QAQ

最后的三个出答案的循环太难写+难理解了,垃圾如我:D

磕磕绊绊最后还是码出来了;

大概学到了一些小知识?

pair相当于把两个数据整合成一个数据,就像结构体一样,第一个是first,第二个是second;

定义→pair <数据类型,数据类型> 变量名;

http://blog.csdn.net/hiwoshixiaoyu/article/details/53894162

具体↑

greater<>里面可以用pair,比较的是第一个数据,如果第一个数据一样就比较第二个;

其他大概是加深了对邻接表的理解????

时间: 2024-08-01 00:06:37

JZYZOJ1525 HAOI2012道路 堆优化的dijkstra+pair的相关文章

堆优化的Dijkstra

SPFA在求最短路时不是万能的.在稠密图时用堆优化的dijkstra更加高效: 1 typedef pair<int,int> pii; 2 priority_queue<pii, vector<pii>, greater<pii> > q 3 void dijkstra(){ 4 memset(dis,10,sizeof(dis)); 5 memset(vis,0,sizeof(vis)); 6 dis[K]=0; 7 q.push(make_pair(d

POJ1797 Heavy Transportation (堆优化的Dijkstra变形)

Background Hugo Heavy is happy. After the breakdown of the Cargolifter project he can now expand business. But he needs a clever man who tells him whether there really is a way from the place his customer has build his giant steel crane to the place

Heap+Dijkstra堆优化的Dijkstra

前面说到"原生的Dijkstra",由于Dijkstra采用的是贪心策略,在贪心寻找当前距离源结点最短的结点时需要遍历所有的结点,这必然会导致效率的下降,时间复杂度为n^n.因此当数据量较大时会消耗较长时间.为了提高Dijkstra的效率,只有对Dijkstra的贪心策略进行改进. 由于Dijkstra采用的贪心策略是每次寻找最短距离的结点并将其放入存放所有已知最短距离结点的S集合中,可以联想到堆以及优先级队列这些数据结构,这些结构都能非常高效地提供当前状态距离最短的结点.实践也可以证

HDU4725 The Shortest Path in Nya Graph(堆优化的dijkstra算法)

题意: 这是一个非常容易解决的问题,您的任务只是计算图像,而仅是计算干草成本和算法成本.如果您不懂此段话,请继续.Nya图是具有“层”的无向图.图中的每个节点都属于一个层,总共有N个节点.您可以以成本C从x层中的任何节点移动到x + 1层中的任何节点,因为道路是双向的,因此也可以以相同的成本从x + 1层移动到x层.此外,还有M个额外的边,每个边连接一对节点u和v,成本为w.帮助我们计算从节点1到节点N的最短路径. 题解: 主要是建图. N个点,然后有N层,要假如2*N个点. 总共是3*N个点.

【51nod1443】路径和树(堆优化dijkstra乱搞)

点此看题面 大致题意:给你一个无向联通图,要求你求出这张图中从u开始的权值和最小的最短路径树的权值之和. 什么是最短路径树? 从\(u\)开始到任意点的最短路径与在原图中相比不变. 题解 既然要求最短路径,那么最容易想到的就是\(dijkstra\)和\(SPFA\)(毕竟Floyd的时间复杂度难以承受),又由于黄学长说能用\(dijkstra\)时尽量用\(dijkstra\),所以,我就打了一个堆优化的\(dijkstra\)开始乱搞. 其实,这道题目的思路真的挺简单的,只要朴素地做一遍\(

[转]浅谈dijkstra堆优化

众所周知的,dijkstra是图论算法中求单源最短路的一种简单求法.可能有人会说SPFA比dijkstra要实用,而且可以用于求存在负边权的情况,但是dijkstra有着他的优点——其运行速度上优于SPFA. (PS.需要堆进行优化.) 我们先看一道经典(水)题: 平面上有n个点(n<=100),每个点的坐标均在-10000~10000之间.其中的一些点之间有连线. 若有连线,则表示可从一个点到达另一个点,即两点之间有通路,通路的距离为两点之间的直线距离.现在的任务是找出从入点到出点之间的最短路

Dijkstra+优先队列 堆优化

代码 #include <cstdio> #include <queue> #include <vector> #define MAXN 200010 #define INF 0x3fffffff using namespace std; struct edge{ int v,w; edge(int v, int w):v(v),w(w){} }; vector <edge> mp[MAXN]; int dis[MAXN]; bool vis[MAXN];

【Dijstra堆优化】HDU 3986 Harry Potter and the Final Battle

http://acm.hdu.edu.cn/showproblem.php?pid=3986 [题意] 给定一个有重边的无向图,T=20,n<=1000,m<=5000 删去一条边,使得1~n的最短路最长 求最短路最长是多少 [思路] 一定是删最短路上的边 可以先跑一个Dijkstra,求出最短路,然n后枚举删边 朴素的Dijkstra为n^2,枚举删边(n条)需要的总时间复杂度是n^3 堆优化Dijkstra(nlogn),总复杂度为n^2logn 有多重边,用邻接矩阵不方便,用邻接表方便,

【bzoj1097】[POI2007]旅游景点atr 状压dp+堆优化Dijkstra

题目描述 FGD想从成都去上海旅游.在旅途中他希望经过一些城市并在那里欣赏风景,品尝风味小吃或者做其他的有趣的事情.经过这些城市的顺序不是完全随意的,比如说FGD不希望在刚吃过一顿大餐之后立刻去下一个城市登山,而是希望去另外什么地方喝下午茶.幸运的是,FGD的旅程不是既定的,他可以在某些旅行方案之间进行选择.由于FGD非常讨厌乘车的颠簸,他希望在满足他的要求的情况下,旅行的距离尽量短,这样他就有足够的精力来欣赏风景或者是泡MM了^_^.整个城市交通网络包含N个城市以及城市与城市之间的双向道路M条