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 }

 

posted @ 2019-08-24 18:10  IAT14  阅读(386)  评论(0编辑  收藏  举报