A*算法超内存。
对于最短路,我们可以维护dis[]数组,来求得最短路,但是此题有次短路,所以定义dis[][2],dis[][0]表示最短路,dis[][1]表示次短路;cnt[][2],cnt[][0]表示最短路条数,cnt[][1]表示次短路条数。
更新时:
如果小于最短路,更新dis[][0]。
如果等于最短路,更新cnt[][0]。
如果大于最短路小于次短路,更新dis[][1];
如果等于次短路,更新cnt[][1]。
由于此时要求2条路,若以外层循环需要2*n-1次。
以下为dijkstra:
#include<stdio.h> #include<string.h> #define INF 1000000001 const int maxn = 1020; const int maxm = 10010; struct node { int to; int v; int next; }edge[maxn*maxn/2]; int pre[maxn],index,dis[maxn][2],cnt[maxn][2],n,vis[maxn][2]; void init() { index=1; memset(pre,-1,sizeof(pre)); } void add(int x,int y,int z) { edge[index].to=y; edge[index].v=z; edge[index].next=pre[x]; pre[x]=index++; } void dij(int s,int t) { int i,j,k,pos; for(i=0;i<=n;i++) { dis[i][0]=INF; dis[i][1]=INF; cnt[i][0]=cnt[i][1]=0; vis[i][0]=vis[i][1]=0; } dis[s][0]=0; cnt[s][0]=1; pos=s; k=0; for(i=1;i<2*n;i++) { int min=INF; for(j=1;j<=n;j++) { if(!vis[j][0]&&min>dis[j][0]) { min=dis[j][0]; k=0; pos=j; } else if(!vis[j][1]&&min>dis[j][1]) { min=dis[j][1]; k=1; pos=j; } } if(min>=INF) break; vis[pos][k]=1; for(j=pre[pos];j!=-1;j=edge[j].next) { int v=edge[j].to; if(dis[v][0]>min+edge[j].v) { dis[v][1]=dis[v][0];// cnt[v][1]=cnt[v][0]; dis[v][0]=min+edge[j].v; cnt[v][0]=cnt[pos][k]; } else if(dis[v][0]==min+edge[j].v) { cnt[v][0]+=cnt[pos][k]; } else if(dis[v][1]>min+edge[j].v) { dis[v][1]=min+edge[j].v; cnt[v][1]=cnt[pos][k]; } else if(dis[v][1]==min+edge[j].v) { cnt[v][1]+=cnt[pos][k]; } } } int ans=cnt[t][0]; if(dis[t][1]==dis[t][0]+1) ans+=cnt[t][1]; printf("%d ",ans); } int main() { int i,j,ft,m; scanf("%d",&ft); while(ft--) { init(); scanf("%d%d",&n,&m); for(i=0;i<m;i++) { int x,y,z; scanf("%d%d%d",&x,&y,&z); add(x,y,z); } int s,t; scanf("%d%d",&s,&t); dij(s,t); } }
以下为A*算法(超内存):
#include<stdio.h> #include<string.h> #include<queue> #define INF 100000001 using namespace std; const int maxn = 1002; struct node { int to; int g,f; friend bool operator<(node a,node b){ if(a.f!=b.f) return a.f>b.f; return a.g>b.g; } }; struct Enode { int to; int v; int next; }edge[10010],fedge[10010]; int pre[maxn],index,vis[maxn],n,findex,fpre[maxn],dis[maxn]; void init() { findex=index=1; memset(fpre,-1,sizeof(fpre)); memset(pre,-1,sizeof(pre)); } void add(int x,int y,int z) { edge[index].to=y; edge[index].v=z; edge[index].next=pre[x]; pre[x]=index++; } void fadd(int x,int y,int z) { fedge[findex].to=y; fedge[findex].v=z; fedge[findex].next=fpre[x]; fpre[x]=findex++; } void spfa(int s) { int i,j; queue<int>q; for(i=0;i<=n;i++) { vis[i]=0; dis[i]=INF; } dis[s]=0; vis[s]=1; q.push(s); while(!q.empty()) { int t=q.front(); q.pop(); vis[t]--; for(i=fpre[t];i!=-1;i=fedge[i].next) { int v=fedge[i].to; if(dis[v]>dis[t]+fedge[i].v) { dis[v]=dis[t]+fedge[i].v; q.push(v); } } } } void A_star(int s,int t) { int i,j,cnt=0,first=-1; priority_queue<node>q; node temp; temp.f=dis[s]; temp.g=0; temp.to=s; q.push(temp); while(!q.empty()) { temp=q.top(); q.pop(); if(temp.to==t) { if(cnt==0) { first=temp.g; } else if(temp.g-first>1) { break; } cnt++; } for(i=pre[temp.to];i!=-1;i=edge[i].next) { node tt; tt.to=edge[i].to; tt.g=temp.g+edge[i].v; tt.f=tt.g+dis[tt.to]; q.push(tt); } } printf("%d ",cnt); } int main() { int i,j,ft,m; scanf("%d",&ft); while(ft--) { init(); scanf("%d%d",&n,&m); for(i=0;i<m;i++) { int x,y,z; scanf("%d%d%d",&x,&y,&z); add(x,y,z); fadd(y,x,z); } int s,t; scanf("%d%d",&s,&t); spfa(t); A_star(s,t); } }