题意:给一个有向图,告诉起点和终点,求第K短路
解法:dijkstra+A*,正反两个邻接表
总结:做完这个题学会了dijkstra算法,对A*有了一点了解
PS.优先队列里的比较函数变量写错了,MLE了3天,恶心死我了。膜拜无语神牛,几分钟就指导我搞定了
/* Problem: 2449 User: fancy081 Memory: 6472K Time: 250MS Language: C++ Result: Accepted */ #include<cstdio> #include<queue> #include<cstring> using namespace std; const int MAXN=1005; const int MAXM=100005; const int INF=100000000; int N,M,Start,Te,Kth; short v[MAXM],rev[MAXM],w[MAXM]; int next[MAXM]; int renext[MAXM]; int first[MAXN],refirst[MAXN]; int h[MAXN]; struct nod { int len,pos; bool operator<(const nod &x)const { return x.len<len; } }; priority_queue<nod> Que; void dijkstra() { bool done[MAXN]; while(!Que.empty()) Que.pop(); for(int i=1;i<=N;i++) {h[i]=INF;done[i]=false;} h[Te]=0; nod tmp,iq; tmp.len=0;tmp.pos=Te; Que.push(tmp); int uu,vv,dd; while(!Que.empty()) { tmp=Que.top();Que.pop(); uu=tmp.pos; if(done[uu]) continue; dd=tmp.len; done[uu]=true; for(vv=refirst[uu];vv!=-1;vv=renext[vv]) { if(dd+w[vv]<h[rev[vv]]) { h[rev[vv]]=dd+w[vv]; iq.len=h[rev[vv]]; iq.pos=rev[vv]; Que.push(iq); } } } } struct nodx { int f,pos; bool operator<(const nodx &x)const { return x.f<f; } }; priority_queue<nodx> Quex; int astar() { nodx tmp,iq; while(!Quex.empty()) Quex.pop(); int cnt[MAXN]; for(int i=1;i<=N;i++) cnt[i]=0; tmp.f=h[Start];tmp.pos=Start; Quex.push(tmp); int ff,now,gg,vv; while(!Quex.empty()) { tmp=Quex.top();Quex.pop(); ff=tmp.f;now=tmp.pos; gg=tmp.f-h[now]; cnt[now]++; if(cnt[now]>Kth) continue; if(cnt[Te]==Kth) return ff; for(vv=first[now];vv!=-1;vv=next[vv]) { iq.f=gg+w[vv]+h[v[vv]]; iq.pos=v[vv]; Quex.push(iq); } } return -1; } int main() { while(scanf("%d%d",&N,&M)!=EOF) { for(int i=0;i<=N;i++) {first[i]=-1;refirst[i]=-1;} for(int e=0;e<M;e++) { scanf("%d%d%d",&rev[e],&v[e],&w[e]); next[e]=first[rev[e]]; first[rev[e]]=e; renext[e]=refirst[v[e]]; refirst[v[e]]=e; } scanf("%d%d%d",&Start,&Te,&Kth); if(Start==Te) Kth++; dijkstra(); printf("%d\n",astar()); } return 0; }