标签:
感觉所谓Astar并不是单纯的Astar....
能够直接按照优先队列的出队顺序拿到前k短路真神奇......
感觉上大概可以证明,如果当前拿到了第k短路那么之前的k-1短路都已经拿到了?
AC POJ 2449
裸的第k短路.
1 #include <cstdio>
2 #include <fstream>
3 #include <iostream>
4
5 #include <cstdlib>
6 #include <cstring>
7 #include <algorithm>
8 #include <cmath>
9
10 #include <queue>
11 #include <vector>
12 #include <map>
13 #include <set>
14 #include <stack>
15 #include <list>
16
17 typedef unsigned int uint;
18 typedef long long int ll;
19 typedef unsigned long long int ull;
20 typedef double db;
21
22 using namespace std;
23
24 inline int getint()
25 {
26 int res=0;
27 char c=getchar();
28 bool mi=false;
29 while(c<‘0‘ || c>‘9‘) mi=(c==‘-‘),c=getchar();
30 while(‘0‘<=c && c<=‘9‘) res=res*10+c-‘0‘,c=getchar();
31 return mi ? -res : res;
32 }
33 inline ll getll()
34 {
35 ll res=0;
36 char c=getchar();
37 bool mi=false;
38 while(c<‘0‘ || c>‘9‘) mi=(c==‘-‘),c=getchar();
39 while(‘0‘<=c && c<=‘9‘) res=res*10+c-‘0‘,c=getchar();
40 return mi ? -res : res;
41 }
42
43
44 //=============================================================================
45 //=============================================================================
46 //=============================================================================
47 //=============================================================================
48
49 const int INF=(1<<30)-1;
50
51 struct edge
52 {
53 int in;
54 int v;
55 edge*nxt;
56 }pool[105000];
57 edge*et=pool;
58 edge*eds[1050];
59 void addedge(int i,int j,int v)
60 { et->in=j; et->v=v; et->nxt=eds[i]; eds[i]=et++; }
61 #define FOREACH_EDGE(i,j) for(edge*i=eds[j];i;i=i->nxt)
62
63 int A[105000];
64 int B[105000];
65 int V[105000];
66
67 int n,m;
68 int st,ed;
69 int k;
70
71 int dist[1050];
72
73 typedef pair<int,int> pl;
74 void SPFA(int st)
75 {
76 priority_queue<pl,vector<pl>,greater_equal<pl> > q;
77 for(int i=0;i<=n;i++) dist[i]=INF;
78 dist[st]=0;
79 q.push(pl(dist[st],st));
80 while(!q.empty())
81 {
82 int x=q.top().second;
83 int d=q.top().first;
84 q.pop();
85 if(dist[x]<d) continue;
86 FOREACH_EDGE(i,x)
87 if(dist[i->in]>dist[x]+i->v)
88 {
89 dist[i->in]=dist[x]+i->v;
90 q.push(pl(dist[i->in],i->in));
91 }
92 }
93 }
94
95 struct value{ int x,H,s; value(int a,int b,int c):x(a),s(b),H(c){} };
96 bool operator<(const value&a,const value&b)
97 { return a.H>=b.H; }
98
99 int ASTAR_BFS(int st,int ed)
100 {
101 if(dist[st]==INF) return -1;
102 if(st==ed) k++;
103 priority_queue<value> q;
104 q.push(value(st,0,dist[st]+0));
105 while(!q.empty())
106 {
107 int x=q.top().x;
108 int s=q.top().s;
109 q.pop();
110
111 if(x==ed)
112 {
113 k--;
114 if(k==0) return s;
115 }
116
117 FOREACH_EDGE(i,x)
118 q.push(value(i->in,s+i->v,dist[i->in]+s+i->v));
119 }
120 return -1;
121 }
122
123
124
125 int main()
126 {
127 while(scanf("%d%d",&n,&m)>0)
128 {
129 et=pool;
130 memset(eds,0,sizeof(edge*)*(n+1));
131
132 for(int i=0;i<m;i++)
133 {
134 A[i]=getint()-1;
135 B[i]=getint()-1;
136 V[i]=getint();
137 addedge(B[i],A[i],V[i]);
138 }
139
140 st=getint()-1;
141 ed=getint()-1;
142 k=getint();
143
144 SPFA(ed);
145
146 et=pool;
147 memset(eds,0,sizeof(edge*)*(n+1));
148 for(int i=0;i<m;i++)
149 addedge(A[i],B[i],V[i]);
150
151 printf("%d\n",ASTAR_BFS(st,ed));
152 }
153
154 return 0;
155 }
这份代码挤进并列rank10到rank17.....
改成手写堆或许会更快?......
AC BZOJ 1975
裸的前k短路枚举.
1 #include <cstdio>
2 #include <fstream>
3 #include <iostream>
4
5 #include <cstdlib>
6 #include <cstring>
7 #include <algorithm>
8 #include <cmath>
9
10 #include <queue>
11 #include <vector>
12 #include <map>
13 #include <set>
14 #include <stack>
15 #include <list>
16
17 typedef unsigned int uint;
18 typedef long long int ll;
19 typedef unsigned long long int ull;
20 typedef double db;
21
22 using namespace std;
23
24 inline int getint()
25 {
26 int res=0;
27 char c=getchar();
28 bool mi=false;
29 while(c<‘0‘ || c>‘9‘) mi=(c==‘-‘),c=getchar();
30 while(‘0‘<=c && c<=‘9‘) res=res*10+c-‘0‘,c=getchar();
31 return mi ? -res : res;
32 }
33 inline ll getll()
34 {
35 ll res=0;
36 char c=getchar();
37 bool mi=false;
38 while(c<‘0‘ || c>‘9‘) mi=(c==‘-‘),c=getchar();
39 while(‘0‘<=c && c<=‘9‘) res=res*10+c-‘0‘,c=getchar();
40 return mi ? -res : res;
41 }
42
43 //==============================================================================
44 //==============================================================================
45 //==============================================================================
46 //==============================================================================
47
48
49 struct edge
50 {
51 int in;
52 db v;
53 edge*nxt;
54 }pool[405000];
55 edge*et=pool;
56 edge*eds[2][5050];
57 void addedge(int i,int j,db v,int k)
58 { et->in=j; et->v=v; et->nxt=eds[k][i]; eds[k][i]=et++; }
59 #define FOREACH_EDGE(i,x,k) for(edge*i=eds[k][x];i;i=i->nxt)
60
61 int n,m;
62 db E;
63
64 int st,ed;
65 db dist[5050];
66 void SPFA()
67 {
68 for(int i=0;i<n;i++) dist[i]=1e40;
69 typedef pair<db,int> pl;
70 priority_queue<pl,vector<pl>,greater_equal<pl> > q;
71 dist[ed]=0;
72 q.push(pl(dist[ed],ed));
73 while(!q.empty())
74 {
75 int x=q.top().second;
76 db d=q.top().first;
77 q.pop();
78 if(dist[x]<d) continue;
79 FOREACH_EDGE(i,x,1)
80 if(dist[i->in]>dist[x]+i->v)
81 {
82 dist[i->in]=dist[x]+i->v;
83 q.push(pl(dist[i->in],i->in));
84 }
85 }
86 }
87
88 int cnt=0;
89
90 struct value{ db s,f; int x; value(){} value(db a,db b,int x):s(a),f(b),x(x){} };
91 bool operator<(const value&a,const value&b)
92 { return a.f>b.f; }
93
94 value heap[2000000];
95 int htot=0;
96
97 void ASTAR_BFS()
98 {
99 if(dist[st]==1e40) return ;
100 push_heap(heap,heap+htot); htot++;
101 while(htot!=0)
102 {
103 value c=heap[0];
104 pop_heap(heap,heap+htot); htot--;
105
106 if(c.x==ed)
107 {
108 if(c.s>E) break;
109 E-=c.s;
110 cnt++;
111 continue;
112 }
113
114 FOREACH_EDGE(i,c.x,0)
115 {
116 heap[htot++]=value(c.s+i->v,c.s+i->v+dist[i->in],i->in);
117 push_heap(heap,heap+htot);
118 }
119
120 }
121 }
122
123
124 int main()
125 {
126 n=getint();
127 m=getint();
128 scanf("%lf\n",&E);
129 for(int i=0;i<m;i++)
130 {
131 int a,b;
132 db c;
133 a=getint()-1;
134 b=getint()-1;
135 scanf("%lf",&c);
136 addedge(a,b,c,0);
137 addedge(b,a,c,1);
138 }
139 st=0;
140 ed=n-1;
141
142
143 SPFA();
144
145 //for(int i=0;i<n;i++) printf("%f ",dist[i]); printf("\n");
146
147 ASTAR_BFS();
148
149 printf("%d\n",cnt);
150
151
152 return 0;
153 }
MLE了一发...听说priority_queue的空间是普通堆的两倍.......
卡空间的时候可以用stl的heap系列函数代替priority_queue =w= 具体看代码......
代码里也稍许更改了多图的存图法......适用于需要构造多个图而边的参数相同的题目.
标签:
原文地址:http://www.cnblogs.com/DragoonKiller/p/4433369.html