poj3463&&hdu1688 次短路(dijkstra)

    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);
    }
}
原文地址:https://www.cnblogs.com/sweat123/p/4893269.html