给出一个无向图,求给定的两个点之间的次短路长度及其条数
顶点数不多,直接用邻接矩阵存储即可
开二维数组dis,dis[i][0]表示从起点到i的最小距离,dis[i][1]表示从起点到i的次短距离
cnt,cnt[i][0]表示从起点到i的最短路条数,cnt[i][1]表示起点到i的次短路条数
vis,vis[i][0]表示起点到i的最小距离已算好,vis[i][1]表示起点到i的次短距离已算好
首先初始化所有cnt、vis为0,dis为INF_MAX,
设起点为s,终点为e
则dis[e][0]=0 cnt[e][0]=1
即到起点到起点的最短距离为0、条数为1
每次取dis中未被取过且最小的出来,进行比较:
如最小值为dis[i][x] (0<=i<n,x=0||1)
1)
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
const int N=51;
int mat[N][N],INF=1e9+7,dis[N][2],cnt[N][2],vis[N][2];
void dij(int n,int s,int e)
{
//priority_queue<int >que;
memset(vis,0,sizeof(vis));
memset(cnt,0,sizeof(cnt));
for(int i=0;i<n;i++)
dis[i][0]=dis[i][1]=INF;
dis[s][0]=0;
cnt[s][0]=1;
int u,x,min;
for(int ti=0;ti<n*2;ti++)
{
min=INF;
for(int i=0;i<n;i++)
if(!vis[i][0]&&dis[i][0]<min)
{
x=0;
u=i;
min=dis[i][0];
}
else if(!vis[i][1]&&dis[i][1]<min)
{
x=1;
u=i;
min=dis[i][1];
}
if(min==INF)
break;
vis[u][x]=1;
for(int i=0;i<n;i++)
if(mat[u][i]!=-1)
{
if(dis[i][0]>min+mat[u][i])
{
dis[i][1]=dis[i][0];
cnt[i][1]=cnt[i][0];
dis[i][0]=min+mat[u][i];
cnt[i][0]=cnt[u][x];
}
else if(dis[i][0]==min+mat[u][i])
{
cnt[i][0]+=cnt[u][x];
}
else if(dis[i][1]>min+mat[u][i])
{
dis[i][1]=min+mat[u][i];
cnt[i][1]=cnt[u][x];
}
else if(dis[i][1]==min+mat[u][i])
{
cnt[i][1]+=cnt[u][x];
}
}
}
}
int main()
{
int n,m,s,e,x,y,w;
while(scanf("%d%d%d%d",&n,&m,&s,&e)>0)
{
memset(mat,-1,sizeof(mat));
for(int i=0;i<m;i++)
{
scanf("%d%d%d",&x,&y,&w);
mat[x][y]=w;
}
dij(n,s,e);
printf("%d %d\n",dis[e][1],cnt[e][1]);
}
}