
2 5 8 1 2 3 1 3 2 1 4 5 2 3 1 2 5 3 3 4 2 3 5 4 4 5 3 1 5 5 6 2 3 1 3 2 1 3 1 10 4 5 2 5 2 7 5 2 7 4 1
3 2
//62MS 444K
#include<stdio.h>
#include<string.h>
#define M 10007
#define inf 0x3f3f3f
int map[M][M],dist[M][2],count[M][2],head[M];
bool vis[M][2];
int n,m,num;
struct E
{
int v,w,to;
} edg[M<<4];
void addedge(int u,int v,int w)
{
edg[num].v=v;
edg[num].w=w;
edg[num].to=head[u];
head[u]=num++;
}
void dijkstra(int s)
{
int pos,min,k;
for(int i=1; i<=n; i++)
{
dist[i][0]=inf;
dist[i][1]=inf;
}
memset(vis,false,sizeof(vis));
count[s][0]=1;
dist[s][0]=0;
for(int i=1; i<2*n; i++)//每个点要用两次
{
pos=-1;
min=inf;
for(int j=1; j<=n; j++)
if(!vis[j][0]&&min>dist[j][0])//找最短路,每个节点先更新最短,然后次短
{
k=0;
min=dist[j][0];
pos=j;
}
else if(!vis[j][1]&&min>dist[j][1])//找次短路
{
k=1;
min=dist[j][1];
pos=j;
}
if(pos==-1)break;//如果找不到最短或者次短就结束
vis[pos][k]=1;
for(int j=head[pos]; j!=-1; j=edg[j].to)
{
int v=edg[j].v;
int len=dist[pos][k]+edg[j].w;
if(len<dist[v][0])//如果新路径比最短路要短
{
dist[v][1]=dist[v][0];//更新最短路径的长度
count[v][1]=count[v][0];//更新最短路径的条数
dist[v][0]=len;//更新次短路径的长度
count[v][0]=count[pos][k];//更新次短路径的条数
}
else if(len==dist[v][0])//如果新路径等于最短路径的长度
count[v][0]+=count[pos][k];//更新最短路径的条数
else if(len<dist[v][1])//如果新路径比最短路长且比次短路短
{
dist[v][1]=len;//更新次短路的长度
count[v][1]=count[pos][k];//更新次短路径的条数
}
else if(len==dist[v][1])//如果新路径长度等于次短路径的长度
count[v][1]+=count[pos][k];//更新次短路径的条数
}
}
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
num=0;
memset(head,-1,sizeof(head));
scanf("%d%d",&n,&m);
int a,b,c,s,t;
for(int i=1; i<=m; i++)
{
scanf("%d%d%d",&a,&b,&c);//因为题目中可能有重变,所以要用临街表存储
addedge(a,b,c);
}
scanf("%d%d",&s,&t);
dijkstra(s);
int ans=count[t][0];
if(dist[t][1]==dist[t][0]+1)//如果次短路比最短路长度多1
ans+=count[t][1];//加上次短路的条数
printf("%d\n",ans);
}
}
HDU 1688 Sightseeing 求最短路和次短路条数之和,布布扣,bubuko.com
HDU 1688 Sightseeing 求最短路和次短路条数之和
原文:http://blog.csdn.net/crescent__moon/article/details/21027355