POJ 2449Remmarguts' Date K短路模板 SPFA+A*

K短路模板,A*+SPFA求K短路。A*中h的求法为在反图中做SPFA,求出到T点的最短路,极为估价函数h(这里不再是估价,而是准确值),然后跑A*,从S点开始(此时为最短路),然后把与S点能达到的点加入堆中,维护堆,再从堆顶取当前g值最小的点(此时为第2短路),再添加相邻的点放入堆中,依此类推······保证第k次从堆顶取到的点都是第k短路(至于为什么,自己想)其实就是A*算法,这里太啰嗦了

 1 #include<queue>
2
#include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 int v[100010],v2[100010],c[100010],c2[100010],s,t,k,duin; 7 int n,m,point[1010],next[100010],cnt=0,point2[1010],next2[100010],cnt2=0; 8 int dist[1010],vis[1010],cont[1010],duig[1000100],duiu[1000100],duif[1000100]; 9 queue<int>q; 10 void insect(int u,int e,int z) 11 {cnt++; next[cnt]=point[u]; point[u]=cnt; v[cnt]=e; c[cnt]=z;} 12 void insect2(int u,int e,int z) 13 {cnt2++; next2[cnt2]=point2[u]; point2[u]=cnt2; v2[cnt2]=e; c2[cnt2]=z;} 14 void spfa() 15 { int e,mp; while (!q.empty()) q.pop(); 16 memset(vis,0,sizeof(vis)); 17 memset(dist,127,sizeof(dist)); 18 dist[t]=0; vis[t]=1; q.push(t); 19 while (!q.empty()) 20 { 21 e=q.front(); q.pop(); vis[e]=0; 22 for (mp=point2[e];mp!=0;mp=next2[mp]) 23 { 24 if (dist[v2[mp]]>dist[e]+c2[mp]) 25 { 26 dist[v2[mp]]=dist[e]+c2[mp]; 27 if (vis[v2[mp]]==0) 28 { 29 vis[v2[mp]]=1; 30 q.push(v2[mp]); 31 } 32 } 33 } 34 } 35 } 36 void swap(int &a,int &b){int c=a;a=b;b=c;} 37 void popdui() 38 { 39 duif[1]=duif[duin]; duiu[1]=duiu[duin]; duig[1]=duig[duin]; 40 duin--; 41 int i=1; 42 while (i<duin) 43 { 44 if (((duif[i]<duif[i*2])||(i*2>duin))&&((duif[i]<duif[i*2+1])||(i*2+1>duin))) 45 return; 46 if (i*2+1<=duin) 47 if (duif[i*2+1]<duif[i*2]) 48 { swap(duif[i],duif[i*2+1]);swap(duig[i],duig[i*2+1]); 49 swap(duiu[i],duiu[i*2+1]);i=i*2+1;} 50 else 51 { swap(duif[i],duif[i*2]);swap(duig[i],duig[i*2]); 52 swap(duiu[i],duiu[i*2]);i=i*2;} 53 else 54 { swap(duif[i],duif[i*2]);swap(duig[i],duig[i*2]); 55 swap(duiu[i],duiu[i*2]);i=i*2;} 56 } 57 } 58 void puss(int vv,int gg,int ff) 59 { 60 duin++; 61 duiu[duin]=vv;duig[duin]=gg;duif[duin]=ff; 62 int i=duin; 63 while (i>1) 64 { 65 if (duif[i]<duif[i/2]) 66 { 67 swap(duif[i],duif[i/2]); 68 swap(duiu[i],duiu[i/2]); 69 swap(duig[i],duig[i/2]); 70 } 71 else return; 72 i=i/2; 73 } 74 } 75 int astar() 76 { 77 memset(cont,0,sizeof(cont)); 78 memset(duif,0,sizeof(duif)); 79 memset(duiu,0,sizeof(duiu)); 80 memset(duig,0,sizeof(duig)); 81 if (s==t) k++; cnt=0; 82 int f,u,now,i; duin=1;duif[1]=dist[s];duiu[1]=s;duig[1]=0; 83 while (duin>0) 84 { 85 f=duif[1]; u=duiu[1]; now=duig[1]; 86 popdui(); 87 if (u==t) cnt++; 88 if (cnt==k) return now; 89 for (i=point[u];i!=0;i=next[i]) 90 { 91 puss(v[i],now+c[i],now+c[i]+dist[v[i]]); 92 } 93 } 94 return -1; 95 } 96 int main() 97 { 98 int i,j,a,b,cc; 99 while (scanf("%d %d\n",&n,&m)!=EOF) 100 { 101 memset(point,0,sizeof(point)); memset(point2,0,sizeof(point2)); 102 memset(next,0,sizeof(next)); memset(next2,0,sizeof(next2)); 103 memset(v,0,sizeof(v)); memset(v2,0,sizeof(v2)); 104 memset(c,0,sizeof(c)); memset(c2,0,sizeof(c2)); 105 cnt=0; cnt2=0; 106 for (i=1;i<=m;++i) 107 { 108 scanf("%d %d %d\n",&a,&b,&cc); 109 insect(a,b,cc); insect2(b,a,cc); 110 } scanf("%d %d %d\n",&s,&t,&k); 111 spfa(); 112 printf("%d\n",astar()); break; 113 } 114 return 0; 115 }

 

posted @ 2015-12-13 21:14  abclzr  阅读(277)  评论(0编辑  收藏  举报