hdu 1688 Sightseeing

題目鏈接: http://acm.hdu.edu.cn/showproblem.php?pid=1688

這個題大概意思是求從s出發,到f的最短路和次短路的條數一共有多少條(注:次短路的長度爲最短路+1)

解決這個題的辦法是:還是開一個二維的數組記錄最小值和次小值,和對應的二維數組記錄最小值的條數和次小值的條數。其他的和dijkstra做第K短路是差不多,不過還要簡單一些,然後統計。

代碼如下:
#include<cstdio>
#include<cstring>
#define MAXN 1005
#define Inf 0x3ffffff

using namespace std;

struct edge
{
int e,c,next;
}st[10005];

int num[MAXN][2],fa[MAXN],n,m,S,F;//num中記錄最短路和次短路的條數,

void Dij()
{
int dis[MAXN][2],ff[MAXN],i,Min,Minj;//dis記錄最小值和次小指(不重複)

for(i=1;i<=n;i++)
{
ff[i]=0;
dis[i][0]=Inf;
dis[i][1]=Inf;
num[i][0]=0;
num[i][1]=0;
}

num[S][0]=1;
dis[S][0]=0;
while(1)
{
Min=Inf;
for(i=1;i<=n;i++)
{
if(ff[i]<2 && dis[i][ff[i]]<Min)
{
Min=dis[i][ff[i]];
Minj=i;
}
}
if(Min==Inf || (Minj==F && ff[F]>0))break;
int f=ff[Minj]++;
for(i=fa[Minj];i;i=st[i].next)
{
int x=st[i].e;
if(ff[x]<2)
{
int M=st[i].c+Min;
if(M<dis[x][ff[x]])
{
if(ff[x]==0)
{
num[x][1]=num[x][0];
dis[x][1]=dis[x][0];
num[x][0]=num[Minj][f];
dis[x][0]=M;
}
else
{
num[x][1]=num[Minj][f];
dis[x][1]=M;
}
}
else if(M==dis[x][ff[x]])
{
num[x][ff[x]]+=num[Minj][f];
}
else if(ff[x]==0)
{
if(st[i].c+Min<dis[x][1])
{
num[x][1]=num[Minj][f];
   dis[x][1]=st[i].c+Min;
}
else if(st[i].c+Min==dis[x][1])
{
num[x][1]+=num[Minj][f];
}
}
}
}
}
if(dis[F][1]==dis[F][0]+1)
num[F][0]+=num[F][1];
printf("%d\n",num[F][0]);
}
void make()
{
int i,now=1,a,b,c;
memset(fa,0,sizeof(fa));
memset(num,0,sizeof(num));
while(m--)
{
scanf("%d%d%d",&a,&b,&c);
st[now].e=b;st[now].c=c;st[now].next=fa[a];fa[a]=now;
now++;
}
scanf("%d%d",&S,&F);
Dij();
}

int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
make();
}
return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章