这道题大意就是求单源次短路。 就是用dij,只不过要用二维数组;
#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
#define mx 100
#define inff 0x3fffffff
struct node
{
int len;
int en;
int next;
}ro[mx];
int n,m;
int dp[mx][2];//表示最短路和次短路的条数
int p[mx];
int num;
void init()
{
memset(p,-1,sizeof(p));
num=0;
}
void add(int st,int en,int len)
{
ro[num].en=en;
ro[num].len=len;
ro[num].next=p[st];
p[st]=num++;
}
int dis[mx][2];//最短路和次短路的长度
bool use[mx][2];//用于标记是否走过
void dij(int st)
{
int i,j;
memset(use,false,sizeof(use));
memset(dp,0,sizeof(dp));
for(j=0;j<n;j++)
// for(i=0;i<2;i++)
{
dis[j][0]=inff;
dis[j][1]=inff;
}
dp[st][0]=1;//最开始最短路只有一条,没有次短路
dis[st][0]=0;
int flag;
int id;
int mi;
for(i=0;i<n*2;i++)
{
mi=inff;
for(j=0;j<n;j++)
{
/*
找出没有走过的并且最短的点
*/
if(dis[j][0]<mi&&!use[j][0])
{
flag=0;
mi=dis[j][0];
id=j;
}
else if(dis[j][1]<mi&&!use[j][1])
{
flag=1;
mi=dis[j][1];
id=j;
}
}
/*
四种情况:
1:当比最短路还短时,原来的最短路更新为次短路,dp次短路条数更新,
dp最短路条数为当前条数;
dis[ww][1]=dis[ww][0];
dis[ww][0]=dis[id][flag]+ro[j].len;
dp[ww][1]=dp[ww][0];
dp[ww][0]=dp[id][flag];
2.当和最短路相同时,更新最短路条数;
dp[ww][0]+=dp[id][flag];
3:当只小于次短路时,更新,并更新dp次短路
dis[ww][1]=dis[id][flag]+ro[j].len;
dp[ww][1]=dp[id][flag];
4:当和次短路长度相同时,更新次短路条数
dp[ww][1]+=dp[id][flag];
*/
use[id][flag]=true;
for(j=p[id];j!=-1;j=ro[j].next)
{
int ww=ro[j].en;
if(dis[ww][0]>dis[id][flag]+ro[j].len)
{
dis[ww][1]=dis[ww][0];
dis[ww][0]=dis[id][flag]+ro[j].len;
dp[ww][1]=dp[ww][0];
dp[ww][0]=dp[id][flag];
}
else if(dis[ww][0]==dis[id][flag]+ro[j].len)
{
dp[ww][0]+=dp[id][flag];
}
else if(dis[ww][1]>dis[id][flag]+ro[j].len)
{
dis[ww][1]=dis[id][flag]+ro[j].len;
dp[ww][1]=dp[id][flag];
}
else if(dis[ww][1]==dis[id][flag]+ro[j].len)
{
dp[ww][1]+=dp[id][flag];
}
}
}
}
int main()
{
int a,b,c;
int s,e;
int g;
while(scanf("%d%d%d%d",&n,&m,&s,&e)!=EOF)
{
init();
for(g=1;g<=m;g++)
{
scanf("%d%d%d",&a,&b,&c);
add(a,b,c);
//
add(b,a,c);//**********注意 题目中的为单向边;我就错在这里
}
dij(s);
printf("%d %d\n",dis[e][1],dp[e][1]);
}
}