hdu 6705 path 堆
求第k短的路径。
每一个路径,必定是由一个路径加一条边构成。而且新得到的路径长度一定长于原先的路径长度。
所以我们最开始把所有出边按长短排序。只要把每个点出发的最短的边加入一个堆。然后每次选出堆里最短的边。pot,pos,len。表示这个路径最后一条边是从pot走了其第pos条出边,到某个点x,路径总长为len。
然后产生两个新的路径。一个还是从pot点走,走pos+1号边。一个是从x点走,走0号边。
1 #include <cstdio> 2 #include <vector> 3 #include <algorithm> 4 #include <queue> 5 using namespace std; 6 typedef long long ll; 7 const int MAXN = 50010; 8 struct edg 9 { 10 int to,val; 11 edg (int _to,int _val):to(_to),val(_val){} 12 friend bool operator < (edg a,edg b) 13 { 14 return a.val < b.val; 15 } 16 }; 17 struct cas 18 { 19 int pot,pos; 20 ll len; 21 cas (int _pot,int _pos,ll _len):pot(_pot),pos(_pos),len(_len){} 22 friend bool operator < (cas a,cas b) 23 { 24 return a.len > b.len; 25 } 26 }; 27 priority_queue <cas> que; 28 vector <edg> vec[MAXN]; 29 int T,n,m,q,tot,maxn,k[MAXN]; 30 ll ans[MAXN]; 31 int main() 32 { 33 for (scanf("%d",&T);T != 0;T--) 34 { 35 for (int i = 1;i <= n;i++) 36 vec[i].clear(); 37 while (que.empty() == false) 38 que.pop(); 39 maxn = tot = 0; 40 scanf("%d%d%d",&n,&m,&q); 41 int tx,ty,tv; 42 for (int i = 1;i <= m;i++) 43 { 44 scanf("%d%d%d",&tx,&ty,&tv); 45 vec[tx].push_back(edg(ty,tv)); 46 } 47 for (int i = 1;i <= q;i++) 48 { 49 scanf("%d",&k[i]); 50 maxn = max(maxn,k[i]); 51 } 52 for (int i = 1;i <= n;i++) 53 sort(vec[i].begin(),vec[i].end()); 54 for (int i = 1;i <= n;i++) 55 if (vec[i].size() != 0) 56 que.push(cas(i,0,vec[i][0].val)); 57 while (que.empty() == false) 58 { 59 cas tp = que.top(); 60 que.pop(); 61 if (tot >= maxn) 62 break; 63 ans[++tot] = tp.len; 64 if (tp.pos + 1 < vec[tp.pot].size()) 65 que.push(cas(tp.pot,tp.pos + 1,tp.len - vec[tp.pot][tp.pos].val + vec[tp.pot][tp.pos + 1].val)); 66 if (vec[vec[tp.pot][tp.pos].to].size() != 0) 67 que.push(cas(vec[tp.pot][tp.pos].to,0,tp.len + vec[vec[tp.pot][tp.pos].to][0].val)); 68 } 69 for (int i = 1;i <= q;i++) 70 printf("%lld\n",ans[k[i]]); 71 } 72 return 0; 73 }
心之所动 且就随缘去吧