1. 程式人生 > >JZYZOJ1525 HAOI2012道路 堆優化的dijkstra+pair

JZYZOJ1525 HAOI2012道路 堆優化的dijkstra+pair

adding com space namespace {} min string 進行 img

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 }
View Code

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,比較的是第一個數據,如果第一個數據一樣就比較第二個; 其他大概是加深了對鄰接表的理解????

JZYZOJ1525 HAOI2012道路 堆優化的dijkstra+pair