JZYZOJ1525 HAOI2012道路 堆优化的dijkstra+pair
|
样例输入
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 }
完全没有进展,迪杰斯特拉部分的堆之类的大部分看不懂,加油啃。。。
几乎是抄着代码过的,还要自己再写一遍.....
大概算是理解时候的备注
c指代经过其他点得到最短路的点
dijkstra算法可以在算出最短路的同时将点的源点的距离排序,然后按照这个
从前往后枚举在最短路上的边可以得到源点到每个点的最短路的数目,记为a[i]
从后往前枚举在最短路上的边可以得到经过每个点有多少条最短路,记为b[i]
然后对于每条边就是 +=a[e[i].from]*b[e[i].go]
↑大神的方法...
用小根堆写迪杰斯特拉来记录c...我觉得我永远想不出来这么神奇的方法QAQ
最后的三个出答案的循环太难写+难理解了,垃圾如我:D
磕磕绊绊最后还是码出来了;
大概学到了一些小知识?
pair相当于把两个数据整合成一个数据,就像结构体一样,第一个是first,第二个是second;
定义→pair <数据类型,数据类型> 变量名;
具体↑
greater<>里面可以用pair,比较的是第一个数据,如果第一个数据一样就比较第二个;
其他大概是加深了对邻接表的理解????