poj 3463 最短路和比最短路小1的路…

利用dijkstra求出最短路和次短路,并求出其路径数

d[1~n] 最短路

d[n+1~2*n] 次短路

ans[2*n] 路径数

每次找出具有最短路径估计值的点,将其标记为确定的最短路径,并用其更新其余的点

 

关键的思路:最短路径递增,所以每次最小的路径为确定的最短路径(也就是dijkstra算法的关键思想)

 

ps这里讲最短路和次短路标记为两个点,是为了更方便的找出具有最短路径估计值的点

 

#include <iostream>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
using namespace std;
const int maxn=2201;
const int inf=1<<30;
struct node
{
    int to,dist;
    struct node *next;
}e[maxn];
int dist[maxn],ans[maxn];

int edgeini(int n) {for(int i=1;i<=2*n;i++) e[i].next=&e[i];}

int edgemake(int from,int to,int dist)
{
    struct node *p;
    p=(struct node *)malloc(sizeof(struct node));
    p->next=e[from].next;
    e[from].next=p;
    p->to=to;
    p->dist=dist;
}

int dijkstra(int t,int n)
{
    int txt[maxn];
    memset(txt,0,sizeof(txt));

    for(int i=1;i<=2*n;i++)
    dist[i]=inf;
    dist[t]=0;
    ans[t]=1;
    for(int i=2;i<=2*n;i++)
    {
        int ted=inf,tmp=2*n+1;
        for(int j=1;j<=2*n;j++)
        if(dist[j]<ted&&txt[j]==0)
        {
            tmp=j;
            ted=dist[j];
        }
        if(tmp==2*n+1) return(0);
        txt[tmp]=1;
        struct node *p;
        p=(struct node *)malloc(sizeof(struct node));
        p=e[tmp].next;

        while(p!=&e[tmp])
        {
//            printf("%d\n",dist[tmp]);
            if(dist[tmp]+p->dist<dist[p->to])
            {
                dist[p->to+n]=dist[p->to];
                dist[p->to]=dist[tmp]+p->dist;
                ans[p->to+n]=ans[p->to];
                ans[p->to]=ans[tmp];
            }
            else if(dist[tmp]+p->dist==dist[p->to])
            ans[p->to]+=ans[tmp];
            else if(dist[tmp]+p->dist<dist[p->to+n])
            {
                dist[p->to+n]=dist[tmp]+p->dist;
                ans[p->to+n]=ans[tmp];
            }
            else if(dist[tmp]+p->dist==dist[p->to+n])
            ans[p->to+n]+=ans[tmp];
            p=p->next;
        }
    }
}

int main()
{
//    freopen("in.txt","r",stdin);
    int tcase;
    scanf("%d",&tcase);
    while(tcase--)
    {
        int n,m;
        scanf("%d %d",&n,&m);
        edgeini(n);
        for(int i=1,from,to,dist;i<=m;i++)
        {
            scanf("%d %d %d",&from,&to,&dist);
            edgemake(from,to,dist);
            edgemake(from+n,to,dist);
//            printf("%d %d %d\n",from,to,dist);
        }
        int t,s;
        scanf("%d %d",&t,&s);
//        printf("%d\n",t);
        dijkstra(t,n);

//        printf("%d %d\n",dist[s],dist[s+n]);

        if(dist[s]+1==dist[s+n])
        printf("%d\n",ans[s]+ans[s+n]);
        else
        printf("%d\n",ans[s]);
//        for(int i=1;i<=n;i++)
//        printf("%d ",dist[i]);

//        for(int i=1;i<=n;i++)
//        printf("%d ",dist[i]);

    }
    return 0;
}

 

你可能感兴趣的:(poj 3463 最短路和比最短路小1的路…)