您的位置:首页 > 其它

POJ3463 Sightseeing——最短路的信息附带

2014-09-08 16:25 330 查看
题目链接点击打开链接

题意:求最短路和比最短路大1的路径的数目。

思路:求最短路和次短路,如果次短路比最短路大1,两者数量相加,否则结果就是最短路的数目。用ans数组记录路径数目。要理解dij的实质,每一个点访问两次,即可求得最短路和次短路~

此题要使用邻接表来做。

AC代码

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<iomanip>
#include<algorithm>
#include<cmath>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<stack>
typedef long long ll;
#define pi acos(-1)
#define eps 1e-6;
using namespace std;
const int inf=1<<28;
const int NV=1005;
const int NE=10005;
int dis[NV][2],vis[NV][2],head[NV],ans[NV][2],ecnt;
struct edge
{
    int v,next,l;
} E[NE];
void add(int u,int v,int l)
{
    E[++ecnt].v=v;
    E[ecnt].l=l;
    E[ecnt].next=head[u];
    head[u]=ecnt;
}
void init(int n)
{
    ecnt=0;
    memset(ans,0,sizeof(ans));
    memset(vis,0,sizeof(vis));
    memset(head,-1,sizeof(head));
    for(int i=0; i<=n; i++) dis[i][0]=dis[i][1]=inf;
}
void dij(int sta,int n)
{
    int i,j,flag,v,l;
    ans[sta][0]=1;
    dis[sta][0]=0;
    for(i=1; i<2*n; i++)
    {
        int index=0,mi=inf;
        for(j=1; j<=n; j++)
        {
            if(!vis[j][0] && mi>dis[j][0])
                mi=dis[index=j][flag=0];
            else if(!vis[j][1] && mi>dis[j][1])
                mi=dis[index=j][flag=1];

        }
        if(!index) break;
        vis[index][flag]=1;
        for(j=head[index]; j!=-1; j=E[j].next)
        {
            v=E[j].v,l=E[j].l;
            if(dis[v][0]>mi+l)
            {
                dis[v][1]=dis[v][0];
                ans[v][1]=ans[v][0];
                dis[v][0]=mi+l;
                ans[v][0]=ans[index][flag];
            }
            else if(dis[v][0]==mi+l)
            {
                ans[v][0]+=ans[index][flag];
            }
            else if(dis[v][1]>mi+l)
            {
                dis[v][1]=mi+l;
                ans[v][1]=ans[index][flag];
            }
            else if(dis[v][1]==mi+l)
            {
                ans[v][1]+=ans[index][flag];
            }

        }
    }
}
int main()
{
    int t,n,m,u,v,l,sta,ed;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        init(n);
        while(m--)
        {
            scanf("%d%d%d",&u,&v,&l);
            add(u,v,l);
        }
        scanf("%d%d",&sta,&ed);
        dij(sta,n);
        if(dis[ed][0]==dis[ed][1]-1)
            printf("%d\n",ans[ed][0]+ans[ed][1]);
        else
             printf("%d\n",ans[ed][0]);
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: